diff --git a/.gitignore b/.gitignore index 06a51f1b64..73e0407c4b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # log and exec file cmake_targets/log/ cmake_targets/*/build/ +cmake_targets/ran_build/ log/ lte_build_oai/ -targets/bin/ \ No newline at end of file +targets/bin/ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..6757ed47f6 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "enter program name, for example ${workspaceFolder}/a.exe", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/path/to/gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 2f736c5dbd..d16de8b7ab 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -44,7 +44,7 @@ pipeline { disableConcurrentBuilds() timestamps() gitLabConnection('OAI GitLab') - gitlabBuilds(builds: ["Build gNB-USRP", "Build nr-UE-USRP", "Build eNB-USRP", "Build basic-sim", "Build phy-sim", "Build eNB-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-Mono-FDD-Band7", "Test-Mono-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40", "Test-Mono-FDD-Band13", "Test-Mono-FDD-Band13-X2-HO", "Test-TDD-Band78-gNB-NR-UE"]) + gitlabBuilds(builds: ["Build gNB-USRP", "Build nr-UE-USRP", "Build eNB-USRP", "Build basic-sim", "Build phy-sim", "Build eNB-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-Mono-FDD-Band7", "Test-Mono-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40", "Test-Mono-FDD-Band13", "Test-IF4p5-TDD-Band38-Multi-RRU" , "Test-Mono-FDD-Band13-X2-HO", "Test-TDD-Band78-gNB-NR-UE"]) ansiColor('xterm') } @@ -57,6 +57,9 @@ pipeline { echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' def allParametersPresent = true + if (env.TESTPLATFORM_OWNER) { + echo "Platform is ${env.TESTPLATFORM_OWNER}" + } if (params.RedHatRemoteServer == null) { allParametersPresent = false @@ -128,8 +131,8 @@ pipeline { [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.FlexRanRtcGitLabRepository_Credentials}", usernameVariable: 'git_username', passwordVariable: 'git_password'] ]) { sh "git clone https://${git_username}:${git_password}@gitlab.eurecom.fr/flexran/flexran-rtc.git . > ../git_clone.log 2>&1" + sh "git checkout develop >> ../git_clone.log 2>&1" } - sh "sed -i -e 's#add-apt-repository.*cleishm.*neo4j#add-apt-repository ppa:cleishm/neo4j -y#' -e 's#libneo4j-client-dev#libneo4j-client-dev -y#' tools/install_dependencies" sh "zip -r -qq flexran.zip ." } } @@ -362,7 +365,7 @@ pipeline { stage ("Test physical simulators") { steps { script { - timeout (time: 45, unit: 'MINUTES') { + timeout (time: 90, unit: 'MINUTES') { try { gitlabCommitStatus(name: "Test phy-sim") { sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" @@ -575,6 +578,25 @@ pipeline { } } } + stage ("Test IF4p5 - TDD - Band 38 - B210 - MultiRRU") { + steps { + script { + triggerSlaveJob ('eNB-CI-IF4p5-TDD-Band38-MultiRRU-B210', 'Test-IF4p5-TDD-Band38-Multi-RRU') + } + } + post { + always { + script { + finalizeSlaveJob('eNB-CI-IF4p5-TDD-Band38-MultiRRU-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } stage ("Test OAI UE - FDD - Band 20 - B200") { steps { script { diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index ae6b48cd51..72fa29aa39 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -44,7 +44,7 @@ function build_on_vm { STATUS=1 return fi - if [ ! -f /etc/apt/apt.conf.d/01proxy ] + if [[ ! -f /etc/apt/apt.conf.d/01proxy ]] && [[ "$OPTIONAL_APTCACHER" != "true" ]] then echo "Missing /etc/apt/apt.conf.d/01proxy file!" echo "Is apt-cacher installed and configured?" @@ -68,11 +68,12 @@ function build_on_vm { then echo "VM_MEMORY = $VM_MEMORY MBytes" echo "VM_CPU = $VM_CPU" + echo "VM_DISK = $VM_DISK GBytes" echo "############################################################" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" acquire_vm_create_lock - uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml + uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --unsafe-caching --template ci-scripts/template-host.xml echo "Waiting for VM to be started" uvt-kvm wait $VM_NAME --insecure @@ -96,12 +97,12 @@ function build_on_vm { else scp -o StrictHostKeyChecking=no $JENKINS_WKSP/localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu fi - scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu + [ -f /etc/apt/apt.conf.d/01proxy ] && scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu echo "############################################################" echo "Running install and build script on VM ($VM_NAME)" echo "############################################################" - echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS + echo "[ -f 01proxy ] && sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS echo "touch /home/ubuntu/.hushlogin" >> $VM_CMDS echo "git config --global https.postBuffer 123289600" >> $VM_CMDS if [[ "$VM_NAME" == *"-cppcheck"* ]] @@ -179,8 +180,12 @@ function build_on_vm { echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS echo "echo \"./tools/install_dependencies \"" >> $VM_CMDS echo "./tools/install_dependencies > cmake_targets/log/install-build.txt 2>&1" >> $VM_CMDS + echo "echo \"mkdir build\"" >> $VM_CMDS + echo "mkdir build" >> $VM_CMDS + echo "echo \"cd build\"" >> $VM_CMDS + echo "cd build" >> $VM_CMDS echo "echo \"$BUILD_OPTIONS \"" >> $VM_CMDS - echo "$BUILD_OPTIONS > cmake_targets/log/rt_controller.Rel15.txt 2>&1" >> $VM_CMDS + echo "$BUILD_OPTIONS > ../cmake_targets/log/rt_controller.Rel15.txt 2>&1" >> $VM_CMDS fi if [[ "$VM_NAME" != *"-cppcheck"* ]] && [[ "$VM_NAME" != *"-flexran-rtc"* ]] then diff --git a/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf index eff8b68857..ab89d13193 100644 --- a/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf +++ b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf @@ -233,6 +233,7 @@ eNBs = #pdsch_maxNumRepetitionCEmodeB_r13 = "r384"; # NULL - 2 pusch_maxNumRepetitionCEmodeA_r13 = "r8"; #0 + pusch_repetitionLevelCEmodeA_r13 = "l1"; #pusch_maxNumRepetitionCEmodeB_r13 = "r768"; #4 #NULL #pusch_HoppingOffset_v1310 = 5; #NULL diff --git a/ci-scripts/createVM.sh b/ci-scripts/createVM.sh index e0e1da4236..237a1a5d5e 100755 --- a/ci-scripts/createVM.sh +++ b/ci-scripts/createVM.sh @@ -85,12 +85,13 @@ function create_vm { echo "VM_NAME = $VM_NAME" echo "VM_MEMORY = $VM_MEMORY MBytes" echo "VM_CPU = $VM_CPU" + echo "VM_DISK = $VM_DISK GBytes" echo "############################################################" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" acquire_vm_create_lock - uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml + uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --unsafe-caching --template ci-scripts/template-host.xml echo "Waiting for VM to be started" uvt-kvm wait $VM_NAME --insecure diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 5a86702cc2..35574512f1 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -128,6 +128,7 @@ class SSHConnection(): self.Build_eNB_args = '' self.backgroundBuild = False self.backgroundBuildTestId = ['', '', ''] + self.Build_eNB_forced_workspace_cleanup = False self.Initialize_eNB_args = '' self.air_interface = 'lte' self.eNB_instance = '' @@ -370,9 +371,16 @@ class SSHConnection(): self.air_interface = 'nr' else: self.air_interface = 'lte' + if self.Build_eNB_forced_workspace_cleanup: + self.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15) + result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) + if result is not None: + full_ran_repo_name = self.ranRepository + else: + full_ran_repo_name = self.ranRepository + '.git' self.command('mkdir -p ' + lSourcePath, '\$', 5) self.command('cd ' + lSourcePath, '\$', 5) - self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) + self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) # Raphael: here add a check if git clone or git fetch went smoothly self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) self.command('git config user.name "OAI Jenkins"', '\$', 5) @@ -537,13 +545,42 @@ class SSHConnection(): ue_prefix = '' self.command('mkdir -p ' + self.UESourceCodePath, '\$', 5) self.command('cd ' + self.UESourceCodePath, '\$', 5) - self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) + self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) # here add a check if git clone or git fetch went smoothly self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) self.command('git config user.name "OAI Jenkins"', '\$', 5) if self.clean_repository: - pass + self.command('ls *.txt', '\$', 5) + result = re.search('LAST_BUILD_INFO', str(self.ssh.before)) + if result is not None: + mismatch = False + self.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2) + result = re.search(self.ranCommitID, str(self.ssh.before)) + if result is None: + mismatch = True + self.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) + if (self.ranAllowMerge): + result = re.search('YES', str(self.ssh.before)) + if result is None: + mismatch = True + self.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) + if self.ranTargetBranch == '': + result = re.search('develop', str(self.ssh.before)) + else: + result = re.search(self.ranTargetBranch, str(self.ssh.before)) + if result is None: + mismatch = True + else: + result = re.search('NO', str(self.ssh.before)) + if result is None: + mismatch = True + if not mismatch: + self.close() + self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) + return + self.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30) + # if the commit ID is provided use it to point to it if self.ranCommitID != '': self.command('git checkout -f ' + self.ranCommitID, '\$', 5) @@ -571,12 +608,23 @@ class SSHConnection(): self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) self.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5) - self.close() if buildStatus: - logging.info('\u001B[1m Building OAI ' + ue_prefix + 'UE Pass\u001B[0m') + # Generating a BUILD INFO file + self.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2) + self.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) + if (self.ranAllowMerge): + self.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2) + if self.ranTargetBranch == '': + self.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2) + else: + self.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) + else: + self.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2) + self.close() self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE') else: - logging.error('\u001B[1m Building OAI ' + ue_prefix + 'UE Failed\u001B[0m') + self.close() + logging.error('\u001B[1m Building OAI UE Failed\u001B[0m') self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', ALL_PROCESSES_OK, 'OAI UE') self.CreateHtmlTabFooter(False) sys.exit(1) @@ -738,13 +786,13 @@ class SSHConnection(): # do not reset board twice in IF4.5 case result = re.search('^rru|^enb|^du.band', str(config_file)) if result is not None: - self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 10) + self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 30) result = re.search('type: b200', str(self.ssh.before)) if result is not None: logging.debug('Found a B2xx device --> resetting it') self.command('echo ' + lPassWord + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) # Reloading FGPA bin firmware - self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 15) + self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 30) # Make a copy and adapt to EPC / eNB IP addresses self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5) self.command('sed -i -e \'s/CI_MME_IP_ADDR/' + self.EPCIPAddress + '/\' ' + ci_full_config_file, '\$', 2); @@ -1138,7 +1186,7 @@ class SSHConnection(): html_queue = SimpleQueue() self.checkDevTTYisUnlocked() if attach_status: - html_cell = '
CAT-M module\nAttachment Completed in ' + str(attach_cnt+4) + ' seconds' + html_cell = 'CAT-M module Attachment Completed in ' + str(attach_cnt+4) + ' seconds' if (nRSRQ is not None) and (nRSRP is not None): html_cell += '\n RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB' html_cell += '\n RSRP = ' + str(-140+nRSRP) + ' dBm' @@ -1147,9 +1195,11 @@ class SSHConnection(): html_queue.put(html_cell) self.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue) else: - html_cell = 'CAT-M module\nAttachment Failed' + logging.error('\u001B[1m CAT-M module Attachment Failed\u001B[0m') + html_cell = 'CAT-M module Attachment Failed' html_queue.put(html_cell) self.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue) + self.AutoTerminateUEandeNB() def PingCatM(self): if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '': @@ -1160,7 +1210,7 @@ class SSHConnection(): pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.prematureExit = True + self.AutoTerminateUEandeNB() return try: statusQueue = SimpleQueue() @@ -1179,6 +1229,8 @@ class SSHConnection(): if result is not None: moduleIPAddr = result.group('ipaddr') else: + self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + self.AutoTerminateUEandeNB() return ping_time = re.findall("-c (\d+)",str(self.ping_args)) device_id = 'catm' @@ -2409,15 +2461,16 @@ class SSHConnection(): os.kill(os.getppid(),signal.SIGUSR1) def IperfNoS1(self): + if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': + Usage() + sys.exit('Insufficient Parameter') check_eNB = True check_OAI_UE = True pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) self.AutoTerminateUEandeNB() - if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': - Usage() - sys.exit('Insufficient Parameter') + return server_on_enb = re.search('-R', str(self.iperf_args)) if server_on_enb is not None: iServerIPAddr = self.eNBIPAddress @@ -3447,6 +3500,11 @@ class SSHConnection(): self.ShowTestID() self.eNB_instance = '0' self.TerminateeNB() + if self.flexranCtrlInstalled and self.flexranCtrlStarted: + self.testCase_id = 'AUTO-KILL-flexran-ctl' + self.desc = 'Automatic Termination of FlexRan CTL' + self.ShowTestID() + self.TerminateFlexranCtrl() self.prematureExit = True def IdleSleep(self): @@ -3716,7 +3774,7 @@ class SSHConnection(): if result is not None: self.UhdVersion = result.group('uhd_version') logging.debug('UHD Version is: ' + self.UhdVersion) - self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 12) + self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 30) usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', str(self.ssh.before)) count = 0 for board in usrp_boards: @@ -4108,6 +4166,14 @@ def CheckClassValidity(action,id): def GetParametersFromXML(action): if action == 'Build_eNB': SSH.Build_eNB_args = test.findtext('Build_eNB_args') + forced_workspace_cleanup = test.findtext('forced_workspace_cleanup') + if (forced_workspace_cleanup is None): + SSH.Build_eNB_forced_workspace_cleanup = False + else: + if re.match('true', forced_workspace_cleanup, re.IGNORECASE): + SSH.Build_eNB_forced_workspace_cleanup = True + else: + SSH.Build_eNB_forced_workspace_cleanup = False SSH.eNB_instance = test.findtext('eNB_instance') if (SSH.eNB_instance is None): SSH.eNB_instance = '0' @@ -4564,7 +4630,11 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re while cnt < SSH.repeatCounts[0] and SSH.prematureExit: SSH.prematureExit = False for test_case_id in todo_tests: + if SSH.prematureExit: + break for test in all_tests: + if SSH.prematureExit: + break id = test.get('id') if test_case_id != id: continue @@ -4645,10 +4715,6 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re SSH.Perform_X2_Handover() else: sys.exit('Invalid action') - if SSH.prematureExit: - break - if SSH.prematureExit: - break cnt += 1 if cnt == SSH.repeatCounts[0] and SSH.prematureExit: logging.debug('Testsuite failed ' + str(cnt) + ' time(s)') diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 7fba7bac79..9d6349077f 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -52,7 +52,7 @@ function variant_usage { if [ "$1" = "full" ] then printf " VM_NAME=%-15s ARCHIVES_LOC=%-15s\n" "$VM_NAME" "$ARCHIVES_LOC" - printf " VM_MEMORY=%-15s VM_CPU=%-15s\n" "$VM_MEMORY" "$VM_CPU" + printf " VM_MEMORY=%-15s VM_CPU=%-15s VM_DISK=%-15s\n" "$VM_MEMORY" "$VM_CPU" "$VM_DISK" printf " NB_PATTERN_FILES=%-15s BUILD_OPTIONS=%-15s\n" "$NB_PATTERN_FILES" "\"$BUILD_OPTIONS\"" printf " LOG_PATTERN=%-15s EXPERIMENTAL=%-15s\n\n\n" "$LOG_PATTERN" "$EXPERIMENTAL" fi @@ -140,10 +140,25 @@ function command_options_usage { echo "" } +# function to set specific behavior depending on the TESTPLATFORM_OWNER variable +# which may be set by a jenkins server for exemple +function platform_set { + if [ "$TESTPLATFORM_OWNER" != "" ] + then + echo "Running on $TESTPLATFORM_OWNER platform" + if [ -x "/usr/local/bin/oai_${TESTPLATFORM_OWNER}_setenv.sh" ] + then + . /usr/local/bin/oai_${TESTPLATFORM_OWNER}_setenv.sh + fi + fi +} + function setvar_usage { declare -A HELP_VAR HELP_VAR["VM_OSREL"]="OS release to use in virtual machines" HELP_VAR["RUN_EXPERIMENTAL"]="Enforce execution of variants with EXPERIMENTAL variable set to \"true\"" + HELP_VAR["OPTIONAL_APTCACHER"]="build and Run tests will fail if apt-cacher not installed and this variable not set to \"true\"" + HELP_VAR["TESTPLATFORM_OWNER"]="Allow pipeline customization via execution of an externel scripts residing on the jenkins server" echo "--setvar_where varname is one of:" for i in ${AUTHORIZED_VAR[@]}; do printf "%20s : %s\n" "$i" "${HELP_VAR[$i]}" ;done } @@ -167,25 +182,30 @@ function variant__v2__basic_sim { } function variant__v3__phy_sim { - NB_PATTERN_FILES=12 + NB_PATTERN_FILES=13 BUILD_OPTIONS="--phy_simulators" VM_MEMORY=8192 - RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" + VM_DISK=20 + RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111\" -q -np -b" } function variant__v4__cppcheck { VM_MEMORY=4096 LOG_PATTERN=cppcheck.xml NB_PATTERN_FILES=1 - BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 --suppressions-list=ci-scripts/cppcheck_suppressions.list -I common/utils -I openair3/NAS/COMMON/UTIL -j4" + BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 -i openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c --suppressions-list=ci-scripts/cppcheck_suppressions.list -I common/utils -I openair3/NAS/COMMON/UTIL -j4" } function variant__v5__gnb_usrp { + VM_MEMORY=8192 + VM_CPU=8 NB_PATTERN_FILES=9 BUILD_OPTIONS="--gNB -w USRP" } function variant__v6__nr_ue_usrp { + VM_MEMORY=4096 + VM_CPU=4 NB_PATTERN_FILES=9 BUILD_OPTIONS="--nrUE -w USRP" } @@ -207,7 +227,7 @@ function variant__v8__ue_ethernet { function variant__v10__flexran_rtc { ARCHIVES_LOC=flexran NB_PATTERN_FILES=1 - BUILD_OPTIONS="cmake . && make -j2" + BUILD_OPTIONS="cmake .. && make -j2" VARIANT_INFO="non-OSA" } @@ -218,8 +238,8 @@ function variant__v20__l1_sim { } function variant__v21__rf_sim { + ARCHIVES_LOC=rf_sim RUN_OPTIONS="complex" - EXPERIMENTAL="true" } function variant__v22__l2_sim { @@ -257,6 +277,7 @@ function check_set_variant { ARCHIVES_LOC=${VARIANTS_LONG[$i]//"-"/"_"} VM_MEMORY=2048 VM_CPU=4 + VM_DISK=10 EXPERIMENTAL="" NBARGS=$[$NBARGS+$VARIANT_OPTID] variant__${VARIANTS_SHORT[$i]}__${VARIANTS_LONG[$i]//"-"/"_"} @@ -328,6 +349,7 @@ function check_setvar { exit 1 } +platform_set MY_DIR=$(dirname $(readlink -f $0)) . $MY_DIR/createVM.sh . $MY_DIR/buildOnVM.sh @@ -337,6 +359,7 @@ MY_DIR=$(dirname $(readlink -f $0)) . $MY_DIR/reportBuildLocally.sh . $MY_DIR/reportTestLocally.sh + if [ $# -lt 1 ] then echo "Syntax Error: too few arguments" @@ -454,7 +477,7 @@ RUN_OPTIONS="none" # list of variables that can be set via the --setvar option -AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL") +AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL OPTIONAL_APTCACHER TESTPLATFORM_OWNER") #variables to set which OS VM should use @@ -477,6 +500,7 @@ AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL") # -V option. VM_NAME="" VM_MEMORY=0 +VM_DISK=0 VM_CPU=0 ARCHIVES_LOC="" LOG_PATTERN="" diff --git a/ci-scripts/rcc-files/rbconfig.raw b/ci-scripts/rcc-files/rbconfig.raw new file mode 100644 index 0000000000..9c561b7a9f --- /dev/null +++ b/ci-scripts/rcc-files/rbconfig.raw @@ -0,0 +1 @@ + (ׂÀ \ No newline at end of file diff --git a/ci-scripts/rcc-files/reconfig.raw b/ci-scripts/rcc-files/reconfig.raw new file mode 100644 index 0000000000..5c5e01afe2 Binary files /dev/null and b/ci-scripts/rcc-files/reconfig.raw differ diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index dd0e6b819c..e087cc04e6 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -97,14 +97,20 @@ function analyzeIperfFiles { FILE_COMPLETE=`egrep -c "Server Report" $IPERF_CASE` if [ $FILE_COMPLETE -eq 0 ] then - echo " KO " >> ./test_simulator_results.html SERVER_FILE=`echo $IPERF_CASE | sed -e "s#client#server#"` FLOAT_EFF_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; printf "%.0f", br}'` - EFFECTIVE_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; if(br>1000000){printf "%.2f MBits/sec", br/1000000}}'` + EFFECTIVE_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; if(br>1000000){printf "%.2f MBits/sec", br/1000000}else{printf "%.2f KBits/sec", br/1000}}'` PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` + PERF_INT=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.0f", $0}'` JITTER=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*/sec *##" -e "s# *ms.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{jitter=s/n; printf "%.3f ms", jitter}'` PACKETLOSS_NOSIGN=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*(##" -e "s#%.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{per=s/n; printf "%.1f", per}'` PACKETLOSS=`echo "${PACKETLOSS_NOSIGN}%"` + if [[ $PERF_INT -lt 80 ]] + then + echo "KO " >> ./test_simulator_results.html + else + echo "OK " >> ./test_simulator_results.html + fi else EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` if [[ $EFFECTIVE_BITRATE =~ .*Kbits/sec.* ]] @@ -394,6 +400,126 @@ function report_test { echo " " >> ./test_simulator_results.html fi + ARCHIVES_LOC=archives/rf_sim/test + if [ -d $ARCHIVES_LOC ] + then + echo "5G NR RF Simulator Check
" >> ./test_simulator_results.html + + if [ -f $ARCHIVES_LOC/test_final_status.log ] + then + if [ `grep -c TEST_OK $ARCHIVES_LOC/test_final_status.log` -eq 1 ] + then + echo "" >> ./test_simulator_results.html + echo " TEST was SUCCESSFUL " >> ./test_simulator_results.html + echo "" >> ./test_simulator_results.html + else + echo "" >> ./test_simulator_results.html + echo " TEST was a FAILURE! " >> ./test_simulator_results.html + echo "" >> ./test_simulator_results.html + fi + else + echo "" >> ./test_simulator_results.html + echo " COULD NOT DETERMINE TEST FINAL STATUS! " >> ./test_simulator_results.html + echo "" >> ./test_simulator_results.html + fi + + echo " " >> ./test_simulator_results.html + echo "" >> ./test_simulator_results.html + echo "" >> ./test_simulator_results.html + fi + ARCHIVES_LOC=archives/l2_sim/test if [ -d $ARCHIVES_LOC ] then diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index e93f23120c..118c4b4d9e 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -274,21 +274,30 @@ function generic_iperf { local LOC_BASE_LOG_FILE=$8 local LOC_PORT_ID=$[$9+5001] local LOC_FG_OR_BG=${10} + # By default the requested bandwidth is in Mbits/sec + if [[ $LOC_REQ_BANDWIDTH =~ .*K.* ]] + then + local IPERF_FORMAT="-fk" + local FORMATTED_REQ_BW=$LOC_REQ_BANDWIDTH + else + local IPERF_FORMAT="-fm" + local FORMATTED_REQ_BW=${LOC_REQ_BANDWIDTH}"M" + fi # Starting Iperf Server - echo "iperf -B ${LOC_ISERVER_BOND_IP} -u -s -i 1 -fm -p ${LOC_PORT_ID}" - echo "nohup iperf -B ${LOC_ISERVER_BOND_IP} -u -s -i 1 -fm -p ${LOC_PORT_ID} > ${LOC_BASE_LOG_FILE}_server.txt 2>&1 &" > ${LOC_ISERVER_CMD} + echo "iperf -B ${LOC_ISERVER_BOND_IP} -u -s -i 1 ${IPERF_FORMAT} -p ${LOC_PORT_ID}" + echo "nohup iperf -B ${LOC_ISERVER_BOND_IP} -u -s -i 1 ${IPERF_FORMAT} -p ${LOC_PORT_ID} > ${LOC_BASE_LOG_FILE}_server.txt 2>&1 &" > ${LOC_ISERVER_CMD} ssh -T -o StrictHostKeyChecking=no ubuntu@${LOC_ISERVER_IP} < ${LOC_ISERVER_CMD} rm ${LOC_ISERVER_CMD} # Starting Iperf Client - echo "iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID}" - echo "echo \"COMMAND IS: iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID}\" > ${LOC_BASE_LOG_FILE}_client.txt" > ${LOC_ICLIENT_CMD} + echo "iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${FORMATTED_REQ_BW} -i 1 ${IPERF_FORMAT} -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID}" + echo "echo \"COMMAND IS: iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${FORMATTED_REQ_BW} -i 1 ${IPERF_FORMAT} -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID}\" > ${LOC_BASE_LOG_FILE}_client.txt" > ${LOC_ICLIENT_CMD} if [ $LOC_FG_OR_BG -eq 0 ] then - echo "iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID} >> ${LOC_BASE_LOG_FILE}_client.txt 2>&1" >> ${LOC_ICLIENT_CMD} + echo "iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${FORMATTED_REQ_BW} -i 1 ${IPERF_FORMAT} -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID} >> ${LOC_BASE_LOG_FILE}_client.txt 2>&1" >> ${LOC_ICLIENT_CMD} echo "tail -3 ${LOC_BASE_LOG_FILE}_client.txt | grep -v datagram" >> ${LOC_ICLIENT_CMD} else - echo "nohup iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID} >> ${LOC_BASE_LOG_FILE}_client.txt 2>&1 &" >> ${LOC_ICLIENT_CMD} + echo "nohup iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${FORMATTED_REQ_BW} -i 1 ${IPERF_FORMAT} -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID} >> ${LOC_BASE_LOG_FILE}_client.txt 2>&1 &" >> ${LOC_ICLIENT_CMD} fi ssh -T -o StrictHostKeyChecking=no ubuntu@${LOC_ICLIENT_IP} < ${LOC_ICLIENT_CMD} rm -f ${LOC_ICLIENT_CMD} @@ -305,19 +314,46 @@ function generic_iperf { function check_iperf { local LOC_BASE_LOG=$1 - local LOC_REQ_BW=$2 + local LOC_REQ_BW=`echo $2 | sed -e "s#K##"` local LOC_REQ_BW_MINUS_ONE=`echo "$LOC_REQ_BW - 1" | bc -l` local LOC_REQ_BW_MINUS_TWO=`echo "$LOC_REQ_BW - 2" | bc -l` local LOC_REQ_BW_MINUS_THREE=`echo "$LOC_REQ_BW - 3" | bc -l` local LOC_IS_DL=`echo $LOC_BASE_LOG | grep -c _dl` local LOC_IS_BASIC_SIM=`echo $LOC_BASE_LOG | grep -c basic_sim` + local LOC_IS_RF_SIM=`echo $LOC_BASE_LOG | grep -c rf_sim` + local LOC_IS_NR=`echo $LOC_BASE_LOG | grep -c tdd_106prb` if [ -f ${LOC_BASE_LOG}_client.txt ] then local FILE_COMPLETE=`egrep -c "Server Report" ${LOC_BASE_LOG}_client.txt` if [ $FILE_COMPLETE -eq 0 ] then - IPERF_STATUS=-1 - echo "File Report not found" + if [[ $LOC_IS_RF_SIM -eq 1 ]] && [[ $LOC_IS_NR -eq 1 ]] + then + echo "no UL integration right now --> normal to have no server report" + if [ -f ${LOC_BASE_LOG}_server.txt ] + then + local EFFECTIVE_BANDWIDTH=`tail -n1 ${LOC_BASE_LOG}_server.txt | sed -e "s#^.*MBytes *##" -e "s#^.*KBytes *##" -e "s#sec.*#sec#"` + if [[ $2 =~ .*K.* ]] + then + local BW_SUFFIX="K" + else + local BW_SUFFIX="M" + fi + if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*${BW_SUFFIX}bits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*${BW_SUFFIX}bits.* ]] + then + echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + else + echo "got LESS than requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + IPERF_STATUS=-1 + fi + else + IPERF_STATUS=-1 + echo "Server File Report not found" + fi + else + IPERF_STATUS=-1 + echo "File Report not found" + fi else local EFFECTIVE_BANDWIDTH=`tail -n3 ${LOC_BASE_LOG}_client.txt | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` if [ $LOC_IS_DL -eq 1 ] && [ $LOC_IS_BASIC_SIM -eq 1 ] @@ -351,40 +387,26 @@ function check_iperf { } function terminate_enb_ue_basic_sim { - # mode = 0 : eNB + UE - # mode = 1 : eNB - # mode = 2 : UE + # mode = 0 : eNB + UE or gNB and NR-UE + # mode = 1 : eNB or gNB + # mode = 2 : UE or NR-UE local LOC_MODE=$3 echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" > $1 if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 1 ] then - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo daemon --name=enb_daemon --stop\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo daemon --name=enb_daemon --stop; fi" >> $1 - fi - if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 2 ] - then - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo daemon --name=ue_daemon --stop\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo daemon --name=ue_daemon --stop; fi" >> $1 - fi - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 - echo "echo \"ps -aux | grep softmodem\"" >> $1 - echo "ps -aux | grep softmodem | grep -v grep" >> $1 - echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" >> $1 - if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 1 ] - then - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGINT lte-softmodem\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGINT lte-softmodem; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall -r --signal SIGINT .*-softmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall -r --signal SIGINT .*-softmodem; fi" >> $1 echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 echo "echo \"ps -aux | grep softmodem\"" >> $1 echo "ps -aux | grep softmodem | grep -v grep" >> $1 echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGKILL lte-softmodem\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGKILL lte-softmodem; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall -r --signal SIGKILL .*-softmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall -r --signal SIGKILL .*-softmodem; fi" >> $1 fi if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 2 ] then - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGKILL lte-uesoftmodem\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGKILL lte-uesoftmodem; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall -r --signal SIGKILL .*-uesoftmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall -r --signal SIGKILL .*-uesoftmodem; fi" >> $1 echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 fi echo "echo \"ps -aux | grep softmodem\"" >> $1 @@ -476,7 +498,7 @@ function install_epc_on_vm { local LOC_EPC_VM_IP_ADDR=`uvt-kvm ip $LOC_EPC_VM_NAME` echo "$LOC_EPC_VM_NAME has for IP addr = $LOC_EPC_VM_IP_ADDR" - scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu + [ -f /etc/apt/apt.conf.d/01proxy ] && scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu # ltebox specific actions (install and start) LTE_BOX_TO_INSTALL=1 @@ -500,7 +522,7 @@ function install_epc_on_vm { echo "############################################################" echo "Install EPC on EPC VM ($LOC_EPC_VM_NAME)" echo "############################################################" - echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $LOC_EPC_VM_CMDS + echo "sudo [ -f 01proxy ] && cp 01proxy /etc/apt/apt.conf.d/" > $LOC_EPC_VM_CMDS echo "touch /home/ubuntu/.hushlogin" >> $LOC_EPC_VM_CMDS echo "echo \"sudo apt-get --yes --quiet install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf\"" >> $LOC_EPC_VM_CMDS echo "sudo apt-get update > zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS @@ -1075,6 +1097,162 @@ function start_rf_sim_ue { } +function start_rf_sim_gnb { + local LOC_GNB_VM_IP_ADDR=$2 + local LOC_LOG_FILE=$3 + local LOC_NB_RBS=$4 + local LOC_CONF_FILE=$5 + # 1 is with S1 and 0 without S1 aka noS1 + local LOC_S1_CONFIGURATION=$6 + echo "cd /home/ubuntu/tmp" > $1 + echo "echo \"sudo apt-get --yes --quiet install daemon \"" >> $1 + echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1 + echo "echo \"source oaienv\"" >> $1 + echo "source oaienv" >> $1 + echo "cd ci-scripts/conf_files/" >> $1 + echo "cp $LOC_CONF_FILE ci-$LOC_CONF_FILE" >> $1 + #echo "sed -i -e 's#N_RB_DL.*=.*;#N_RB_DL = $LOC_NB_RBS;#' -e 's#CI_MME_IP_ADDR#$LOC_EPC_IP_ADDR#' -e 's#CI_ENB_IP_ADDR#$LOC_ENB_VM_IP_ADDR#' -e 's#CI_UE_IP_ADDR#$LOC_UE_VM_IP_ADDR#' ci-$LOC_CONF_FILE" >> $1 + #echo "echo \"grep N_RB_DL ci-$LOC_CONF_FILE\"" >> $1 + #echo "grep N_RB_DL ci-$LOC_CONF_FILE | sed -e 's#N_RB_DL.*=#N_RB_DL =#'" >> $1 + echo "echo \"cd /home/ubuntu/tmp/cmake_targets/ran_build/build/\"" >> $1 + echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 + echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 + if [ $LOC_S1_CONFIGURATION -eq 0 ] + then + echo "echo \"RFSIMULATOR=server ./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --noS1 --nokrnmod 1 --rfsim --phy-test\" > ./my-nr-softmodem-run.sh " >> $1 + fi + echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1 + echo "cat ./my-nr-softmodem-run.sh" >> $1 + echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1 + echo "sudo -E daemon --inherit --unsafe --name=gnb_daemon --chdir=/home/ubuntu/tmp/cmake_targets/ran_build/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-nr-softmodem-run.sh" >> $1 + + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR < $1 + rm $1 + + local i="0" + echo "egrep -c \"got sync\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR < $1` + if [ $CONNECTED -ne 0 ] + then + i="100" + else + i=$[$i+1] + fi + done + rm $1 + if [ $i -lt 50 ] + then + GNB_SYNC=0 + echo "RF-SIM gNB is NOT sync'ed: process still alive?" + else + GNB_SYNC=1 + echo "RF-SIM gNB is sync'ed: waiting for UE(s) to connect" + fi + if [ $LOC_S1_CONFIGURATION -eq 0 ] + then + echo "ifconfig oaitun_enb1 | egrep -c \"inet addr\"" > $1 + # Checking oaitun_enb1 interface has now an IP address + i="0" + while [ $i -lt 10 ] + do + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR < $1` + if [ $CONNECTED -eq 1 ] + then + i="100" + else + i=$[$i+1] + sleep 5 + fi + done + rm $1 + if [ $i -lt 50 ] + then + GNB_SYNC=0 + echo "RF-SIM gNB oaitun_enb1 is DOWN or NOT CONFIGURED" + else + echo "RF-SIM gNB oaitun_enb1 is UP and CONFIGURED" + fi + fi + sleep 10 +} + +function start_rf_sim_nr_ue { + local LOC_NR_UE_VM_IP_ADDR=$2 + local LOC_GNB_VM_IP_ADDR=$3 + local LOC_LOG_FILE=$4 + local LOC_PRB=$5 + local LOC_FREQUENCY=$6 + # 1 is with S1 and 0 without S1 aka noS1 + local LOC_S1_CONFIGURATION=$7 + echo "echo \"sudo apt-get --yes --quiet install daemon \"" > $1 + echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1 + echo "echo \"cd /home/ubuntu/tmp/cmake_targets/ran_build/build/\"" >> $1 + echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 + echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 + if [ $LOC_S1_CONFIGURATION -eq 0 ] + then + echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --numerology 1 -C ${LOC_FREQUENCY}000000 -r $LOC_PRB --nokrnmod 1 --rfsim --phy-test --rcc_config_path /home/ubuntu/tmp/ci-scripts/rcc-files --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1 + fi + echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1 + echo "cat ./my-nr-softmodem-run.sh" >> $1 + echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1 + echo "sudo -E daemon --inherit --unsafe --name=nr_ue_daemon --chdir=/home/ubuntu/tmp/cmake_targets/ran_build/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-nr-softmodem-run.sh" >> $1 + + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1 + rm $1 + + local i="0" + echo "egrep -c \"rfsimulator: Success\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1` + if [ $CONNECTED -ne 0 ] + then + i="100" + else + i=$[$i+1] + fi + done + NR_UE_SYNC=1 + rm $1 + if [ $i -lt 50 ] + then + NR_UE_SYNC=0 + echo "RF-SIM NR-UE is NOT sync'ed w/ gNB" + return + else + echo "RF-SIM NR-UE is sync'ed w/ gNB" + fi + # Checking oaitun_ue1 interface has now an IP address + i="0" + echo "ifconfig oaitun_ue1 | egrep -c \"inet addr\"" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1` + if [ $CONNECTED -eq 1 ] + then + i="100" + else + i=$[$i+1] + fi + done + rm $1 + if [ $i -lt 50 ] + then + NR_UE_SYNC=0 + echo "RF-SIM NR-UE oaitun_ue1 is DOWN or NOT CONFIGURED" + else + echo "RF-SIM NR-UE oaitun_ue1 is UP and CONFIGURED" + fi + sleep 10 +} + + function run_test_on_vm { echo "############################################################" echo "OAI CI VM script" @@ -1089,6 +1267,14 @@ function run_test_on_vm { UE_VM_CMDS=${UE_VM_NAME}_cmds.txt echo "UE_VM_NAME = $UE_VM_NAME" echo "UE_VM_CMD_FILE = $UE_VM_CMDS" + GNB_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#gnb-usrp#" -e "s#rf-sim#gnb-usrp#"` + GNB_VM_CMDS=${GNB_VM_NAME}_cmds.txt + echo "GNB_VM_NAME = $GNB_VM_NAME" + echo "GNB_VM_CMD_FILE = $GNB_VM_CMDS" + NR_UE_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#nr-ue-usrp#" -e "s#rf-sim#nr-ue-usrp#"` + NR_UE_VM_CMDS=${UE_VM_NAME}_cmds.txt + echo "NR_UE_VM_NAME = $NR_UE_VM_NAME" + echo "NR_UE_VM_CMD_FILE = $NR_UE_VM_CMDS" else echo "VM_NAME = $VM_NAME" echo "VM_CMD_FILE = $VM_CMDS" @@ -1113,6 +1299,22 @@ function run_test_on_vm { UE_VM_IP_ADDR=`uvt-kvm ip $UE_VM_NAME` echo "$UE_VM_NAME has for IP addr = $UE_VM_IP_ADDR" + + echo "############################################################" + echo "Waiting for GNB VM to be started" + echo "############################################################" + uvt-kvm wait $GNB_VM_NAME --insecure + + GNB_VM_IP_ADDR=`uvt-kvm ip $GNB_VM_NAME` + echo "$GNB_VM_NAME has for IP addr = $GNB_VM_IP_ADDR" + + echo "############################################################" + echo "Waiting for NR-UE VM to be started" + echo "############################################################" + uvt-kvm wait $NR_UE_VM_NAME --insecure + + NR_UE_VM_IP_ADDR=`uvt-kvm ip $NR_UE_VM_NAME` + echo "$NR_UE_VM_NAME has for IP addr = $NR_UE_VM_IP_ADDR" else echo "############################################################" echo "Waiting for VM to be started" @@ -1149,6 +1351,11 @@ function run_test_on_vm { echo "cp /home/ubuntu/bc-install.txt log" >> $VM_CMDS echo "cd log" >> $VM_CMDS echo "zip -r -qq tmp.zip *.* 0*" >> $VM_CMDS + echo "echo \"############################################################\"" >> $VM_CMDS + echo "echo \"Evaluating remaining memory on disk!\"" >> $VM_CMDS + echo "echo \"############################################################\"" >> $VM_CMDS + echo "echo \"df -h\"" >> $VM_CMDS + echo "df -h" >> $VM_CMDS ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS @@ -1461,7 +1668,7 @@ function run_test_on_vm { fi fi - if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]] + if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-ru-sim.* ]] then PING_STATUS=0 IPERF_STATUS=0 @@ -1661,6 +1868,84 @@ function run_test_on_vm { fi fi + if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]] + then + PING_STATUS=0 + IPERF_STATUS=0 + if [ -d $ARCHIVES_LOC ] + then + rm -Rf $ARCHIVES_LOC + fi + mkdir --parents $ARCHIVES_LOC + + CN_CONFIG="noS1" + CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf + S1_NOS1_CFG=0 + PRB=106 + FREQUENCY=3510 + + ######### start of loop + + echo "############################################################" + echo "${CN_CONFIG} : Starting the gNB" + echo "############################################################" + CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb.log + start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG + + echo "############################################################" + echo "${CN_CONFIG} : Starting the NR-UE" + echo "############################################################" + CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue.log + start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG + if [ $NR_UE_SYNC -eq 0 ] + then + echo "Problem w/ gNB and NR-UE not syncing" + terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2 + terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1 + scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + STATUS=-1 + return + fi + + echo "############################################################" + echo "${CN_CONFIG} : iperf DL -- UE is server and eNB is client" + echo "############################################################" + THROUGHPUT="30K" + CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_dl + get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR + get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1 + generic_iperf $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0 + scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE $THROUGHPUT + + echo "############################################################" + echo "${CN_CONFIG} : Terminate gNB/NR-UE simulators" + echo "############################################################" + terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2 + terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1 + scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC + + ######### end of loop + full_l2_sim_destroy + + echo "############################################################" + echo "Checking run status" + echo "############################################################" + + if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $STATUS -eq 0 ] + then + echo "TEST_OK" > $ARCHIVES_LOC/test_final_status.log + else + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + fi + fi + if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-l2-sim.* ]] then PING_STATUS=0 diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh index 9626e36551..f066dacd81 100755 --- a/ci-scripts/waitBuildOnVM.sh +++ b/ci-scripts/waitBuildOnVM.sh @@ -76,6 +76,8 @@ function wait_on_vm_build { echo "echo \"ps -aux | grep build \"" >> $VM_CMDS echo "while [ \$(ps -aux | grep --color=never build_oai | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS fi + echo "echo \"df -h\"" >> $VM_CMDS + echo "df -h" >> $VM_CMDS ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS rm -f $VM_CMDS diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml index aac71198f1..4dbfe00821 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml @@ -25,10 +25,23 @@" >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html + echo "" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + + EPC_CONFIGS=("noS1") + TRANS_MODES=("tdd") + BW_CASES=(106) + for CN_CONFIG in ${EPC_CONFIGS[@]} + do + for TMODE in ${TRANS_MODES[@]} + do + for BW in ${BW_CASES[@]} + do + echo "Log File Name " >> ./test_simulator_results.html + echo "Command " >> ./test_simulator_results.html + echo "Status " >> ./test_simulator_results.html + echo "Statistics " >> ./test_simulator_results.html + echo "" >> ./test_simulator_results.html + if [[ $CN_CONFIG =~ .*wS1.* ]] + then + echo " " >> ./test_simulator_results.html + ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_gnb.log + UE_LOG=`echo $ENB_LOG | sed -e "s#gnb#ue#"` + if [ -f $ENB_LOG ] && [ -f $UE_LOG ] + then + NAME_ENB=`echo $ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"` + NAME_UE=`echo $UE_LOG | sed -e "s#$ARCHIVES_LOC/##"` + echo "Test with EPC (aka withS1): ${TMODE} -- ${BW}PRB " >> ./test_simulator_results.html + else + echo "Test without EPC (aka noS1): ${TMODE} -- ${BW}PRB " >> ./test_simulator_results.html + fi + echo "" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + fi + #PING_LOGS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping*.log 2> /dev/null` + #analyzePingFiles + + IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_iperf_dl*client*txt 2> /dev/null` + analyzeIperfFiles + + #IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_iperf_ul*client*txt 2> /dev/null` + #analyzeIperfFiles + done + done + done + + echo "$NAME_ENB --- $NAME_UE " >> ./test_simulator_results.html + echo "N/A " >> ./test_simulator_results.html + NB_ENB_GOT_SYNC=`egrep -c "got sync" $ENB_LOG` + NB_ENB_TUNNEL_UP=`egrep -c "Interface oaitun_enb1 successfuly configured" $ENB_LOG` + NB_UE_GOT_SYNC=`egrep -c "rfsimulator: Success" $UE_LOG` + NB_ENB_SYNCED_WITH_UE=`egrep -c "Initial sync: starting PBCH detection" $UE_LOG` + NB_UE_TUNNEL_UP=`egrep -c "Interface oaitun_ue1 successfuly configured" $UE_LOG` + if [ $NB_ENB_GOT_SYNC -gt 0 ] && [ $NB_UE_GOT_SYNC -gt 0 ] && [ $NB_ENB_SYNCED_WITH_UE -gt 0 ] + then + echo "OK " >> ./test_simulator_results.html + else + echo "KO " >> ./test_simulator_results.html + fi + echo "" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + if [ $NB_ENB_GOT_SYNC -gt 0 ] + then + echo "- gNB --> got sync" >> ./test_simulator_results.html + else + echo "- gNB NEVER got sync" >> ./test_simulator_results.html + fi + if [ $NB_ENB_TUNNEL_UP -gt 0 ] + then + echo "- gNB mounted oaitun_enb1 interface" >> ./test_simulator_results.html + else + echo "- gNB NEVER mounted oaitun_enb1 interface" >> ./test_simulator_results.html + fi + if [ $NB_UE_GOT_SYNC -gt 0 ] + then + echo "- NR UE --> got sync" >> ./test_simulator_results.html + else + echo "- NR UE NEVER got sync" >> ./test_simulator_results.html + fi + if [ $NB_ENB_SYNCED_WITH_UE -gt 0 ] + then + echo "- NR UE attached to gNB" >> ./test_simulator_results.html + else + echo "- NR UE NEVER attached to eNB" >> ./test_simulator_results.html + fi + if [ $NB_UE_TUNNEL_UP -gt 0 ] + then + echo "- NR UE mounted oaitun_ue1 interface" >> ./test_simulator_results.html + else + echo "- NR UE NEVER mounted oaitun_ue1 interface" >> ./test_simulator_results.html + fi + echo "EPC-Start log-in + 010101 090101 050101 060101 070101 + + + +Build_eNB +Build eNB (USRP) +-w USRP -c --eNB ++ +Build_OAI_UE +Build OAI UE +-w USRP --UE ++ Initialize_HSS Initialize HSS diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml index a2e74c6de9..3eca883aa6 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml @@ -24,7 +24,7 @@test-05-tm1-nos1-tunnel Test-05MHz-TM1-noS1-tunnel tasks -2 +4 030201 090109 030101 000001 090101 000002 040501 040502 000001 040601 040602 040641 040642 000001 090109 030201 diff --git a/ci-scripts/xml_files/enb_usrp210_band13_epc_closure.xml b/ci-scripts/xml_files/enb_usrp210_band13_epc_closure.xml index 07fb6951f8..e52faa7a31 100644 --- a/ci-scripts/xml_files/enb_usrp210_band13_epc_closure.xml +++ b/ci-scripts/xml_files/enb_usrp210_band13_epc_closure.xml @@ -25,10 +25,16 @@ EPC-Closure log-out + 040202 050201 060201 070201 + + +Terminate_CatM_module +Terminate CAT-M Module +diff --git a/ci-scripts/xml_files/simple_dummy_build.xml b/ci-scripts/xml_files/simple_dummy_build.xml new file mode 100644 index 0000000000..75e5f6339a --- /dev/null +++ b/ci-scripts/xml_files/simple_dummy_build.xml @@ -0,0 +1,41 @@ + + Terminate_HSS Terminate HSS diff --git a/ci-scripts/xml_files/gnb_usrp_build.xml b/ci-scripts/xml_files/gnb_usrp_build.xml index 1b57c077ba..bba92930c5 100644 --- a/ci-scripts/xml_files/gnb_usrp_build.xml +++ b/ci-scripts/xml_files/gnb_usrp_build.xml @@ -34,6 +34,7 @@Build_eNB Build gNB (USRP) --gNB -w USRP +True + diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml index 91280462b7..f8aaafd9a0 100644 --- a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml +++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml @@ -26,6 +26,7 @@build-tab +Build +wrench ++ 010101 + ++ + ++ + +Build_eNB +Build Master eNB (USRP) +-w USRP -c --eNB +0 +0 +tasks 030201 030202 + 050202 @@ -43,4 +44,9 @@ 1 + + diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 426c8cd9fd..f5bec7637c 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -185,7 +185,7 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,${CMAKE_CU # set a flag for changes in the source code # these changes are related to hardcoded path to include .h files set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3 -O3") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g3 -DMALLOC_CHECK_=3 -O2") set(GIT_BRANCH "UNKNOWN") @@ -530,6 +530,7 @@ set (SHLIB_LOADER_SOURCES include_directories("${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/") set(HWLIB_USRP_SOURCE ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp + ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c ) add_library(oai_usrpdevif MODULE ${HWLIB_USRP_SOURCE} ) target_link_libraries(oai_usrpdevif uhd) @@ -1204,7 +1205,6 @@ set(PHY_SRC_COMMON ${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_ul_ref.c ${OPENAIR1_DIR}/PHY/CODING/lte_segmentation.c ${OPENAIR1_DIR}/PHY/CODING/nr_segmentation.c - ${OPENAIR1_DIR}/PHY/CODING/nr_compute_tbs.c ${OPENAIR1_DIR}/PHY/CODING/nr_rate_matching.c ${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c ${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c @@ -1319,6 +1319,7 @@ set(PHY_SRC_UE set(PHY_NR_SRC_COMMON ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach_common.c + ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dci_tools_common.c ) set(PHY_NR_SRC @@ -1340,7 +1341,11 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c + ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c + ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c + ${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c + ${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c ${OPENAIR1_DIR}/PHY/TOOLS/file_output.c ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c #${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c @@ -1386,6 +1391,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c + ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -1478,15 +1484,8 @@ set(RRC_DIR ${OPENAIR2_DIR}/RRC/LTE) set(NR_RRC_DIR ${OPENAIR2_DIR}/RRC/NR) set(NR_UE_RRC_DIR ${OPENAIR2_DIR}/RRC/NR_UE) set(PDCP_DIR ${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0) -set(L2_SRC - ${OPENAIR2_DIR}/LAYER2/openair2_proc.c - ${PDCP_DIR}/pdcp.c - ${PDCP_DIR}/pdcp_fifo.c - ${PDCP_DIR}/pdcp_sequence_manager.c - ${PDCP_DIR}/pdcp_primitives.c - ${PDCP_DIR}/pdcp_util.c - ${PDCP_DIR}/pdcp_security.c - ${PDCP_DIR}/pdcp_netlink.c + +set(LTE_RLC_SRC ${RLC_AM_DIR}/rlc_am.c ${RLC_AM_DIR}/rlc_am_init.c ${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c @@ -1514,6 +1513,29 @@ set(L2_SRC ${RLC_DIR}/rlc.c ${RLC_DIR}/rlc_rrc.c ${RLC_DIR}/rlc_mpls.c + ) + +set(NR_RLC_SRC + ${OPENAIR2_DIR}/LAYER2/nr_rlc/asn1_utils.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_am.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_tm.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_um.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_oai_api.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_pdu.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_sdu.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_ue_manager.c + ) + +set(L2_SRC + ${OPENAIR2_DIR}/LAYER2/openair2_proc.c + ${PDCP_DIR}/pdcp.c + ${PDCP_DIR}/pdcp_fifo.c + ${PDCP_DIR}/pdcp_sequence_manager.c + ${PDCP_DIR}/pdcp_primitives.c + ${PDCP_DIR}/pdcp_util.c + ${PDCP_DIR}/pdcp_security.c + ${PDCP_DIR}/pdcp_netlink.c # ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_eNB.c ${RRC_DIR}/rrc_eNB_endc.c @@ -1525,7 +1547,12 @@ set(L2_SRC ${RRC_DIR}/L2_interface_ue.c ) +set(L2_LTE_SRC + ${LTE_RLC_SRC} + ) + set(L2_NR_SRC + ${NR_RLC_SRC} ${NR_RRC_DIR}/rrc_gNB.c ${NR_RRC_DIR}/nr_rrc_common.c ${NR_RRC_DIR}/L2_nr_interface.c @@ -1544,40 +1571,25 @@ set(L2_SRC_UE ${PDCP_DIR}/pdcp_util.c ${PDCP_DIR}/pdcp_security.c ${PDCP_DIR}/pdcp_netlink.c - ${RLC_AM_DIR}/rlc_am.c - ${RLC_AM_DIR}/rlc_am_init.c - ${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c - ${RLC_AM_DIR}/rlc_am_timer_reordering.c - ${RLC_AM_DIR}/rlc_am_timer_status_prohibit.c - ${RLC_AM_DIR}/rlc_am_segment.c - ${RLC_AM_DIR}/rlc_am_segments_holes.c - ${RLC_AM_DIR}/rlc_am_in_sdu.c - ${RLC_AM_DIR}/rlc_am_receiver.c - ${RLC_AM_DIR}/rlc_am_retransmit.c - ${RLC_AM_DIR}/rlc_am_windows.c - ${RLC_AM_DIR}/rlc_am_rx_list.c - ${RLC_AM_DIR}/rlc_am_reassembly.c - ${RLC_AM_DIR}/rlc_am_status_report.c - ${RLC_TM_DIR}/rlc_tm.c - ${RLC_TM_DIR}/rlc_tm_init.c - ${RLC_UM_DIR}/rlc_um.c - ${RLC_UM_DIR}/rlc_um_fsm.c - ${RLC_UM_DIR}/rlc_um_control_primitives.c - ${RLC_UM_DIR}/rlc_um_segment.c - ${RLC_UM_DIR}/rlc_um_reassembly.c - ${RLC_UM_DIR}/rlc_um_receiver.c - ${RLC_UM_DIR}/rlc_um_dar.c - ${RLC_DIR}/rlc_mac.c - ${RLC_DIR}/rlc.c - ${RLC_DIR}/rlc_rrc.c - ${RLC_DIR}/rlc_mpls.c ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_common.c ${RRC_DIR}/L2_interface_common.c ${RRC_DIR}/L2_interface_ue.c ) + +set(LTE_NR_L2_SRC_UE + ${PDCP_DIR}/pdcp.c + ${PDCP_DIR}/pdcp_fifo.c + ${PDCP_DIR}/pdcp_sequence_manager.c + ${PDCP_DIR}/pdcp_primitives.c + ${PDCP_DIR}/pdcp_util.c + ${PDCP_DIR}/pdcp_security.c + ${PDCP_DIR}/pdcp_netlink.c + ${LTE_RLC_SRC} + ) set(NR_L2_SRC_UE + ${NR_RLC_SRC} ${NR_UE_RRC_DIR}/L2_interface_ue.c ${NR_UE_RRC_DIR}/main_ue.c ${NR_UE_RRC_DIR}/rrc_UE.c @@ -1628,13 +1640,14 @@ set (MAC_SRC_UE ${MAC_DIR}/config_ue.c ) - + set (MAC_NR_SRC_UE ${NR_UE_PHY_INTERFACE_DIR}/NR_IF_Module.c ${NR_UE_MAC_DIR}/config_ue.c ${NR_UE_MAC_DIR}/mac_vars.c ${NR_UE_MAC_DIR}/main_ue_nr.c ${NR_UE_MAC_DIR}/nr_ue_procedures.c + ${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c ) set (ENB_APP_SRC @@ -1665,6 +1678,10 @@ add_library(MAC_UE_NR ${MAC_NR_SRC_UE} ) +add_library(L2_LTE + ${L2_LTE_SRC} + ) + add_library(L2_NR ${L2_NR_SRC} ${MAC_NR_SRC} @@ -1684,8 +1701,8 @@ endif() add_dependencies(L2_UE rrc_flag s1ap_flag x2_flag) add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} ) - -add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_mac_common.c ) + +add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_mac_common.c ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c) include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE") include_directories("${OPENAIR2_DIR}/LAYER2/NR_MAC_UE") @@ -2038,7 +2055,7 @@ add_library(LFDS7 # Simulation library ########################## -add_library(SIMU +set (SIMUSRC ${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c @@ -2049,9 +2066,13 @@ ${OPENAIR1_DIR}/SIMULATION/TOOLS/channel_sim.c ${OPENAIR1_DIR}/SIMULATION/RF/rf.c ${OPENAIR1_DIR}/SIMULATION/RF/dac.c ${OPENAIR1_DIR}/SIMULATION/RF/adc.c -${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c +${OPENAIR_DIR}/targets/ARCH/rfsimulator/apply_channelmod.c +#${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ) +# Simulation library +########################## +add_library( SIMU SHARED ${SIMUSRC} ) add_library(SIMU_ETH ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -2267,6 +2288,10 @@ add_library(minimal_lib ) target_link_libraries(minimal_lib pthread dl ${T_LIB}) +add_executable(nfapi_test + ${OPENAIR_DIR}/openair2/NR_PHY_INTERFACE/nfapi_5g_test.c + ) + add_executable(replay_node ${OPENAIR_TARGETS}/ARCH/rfsimulator/stored_node.c ) @@ -2309,7 +2334,7 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag) target_link_libraries (lte-softmodem -Wl,--start-group RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB - PHY_COMMON PHY PHY_RU LFDS L2 NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 + PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} -Wl,--end-group z dl) @@ -2357,7 +2382,6 @@ add_executable(lte-uesoftmodem ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/ru_control.c ${OPENAIR_TARGETS}/RT/USER/rfsim.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c @@ -2382,7 +2406,7 @@ endif() target_link_libraries (lte-uesoftmodem -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP F1AP_LIB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON - PHY_UE PHY_RU LFDS L2_UE SIMU ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} + PHY_UE PHY_RU LFDS L2_UE L2_LTE SIMU ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl) @@ -2431,44 +2455,6 @@ target_link_libraries (nr-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRY target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-softmodem ${T_LIB}) -# nr-softmodem-nos1 -################################################### - -add_executable(nr-softmodem-nos1 - ${rrc_h} - ${s1ap_h} -# ${OPENAIR_BIN_DIR}/messages_xml.h - ${OPENAIR_DIR}/executables/nr-gnb.c - ${OPENAIR_DIR}/executables/nr-ru.c - ${OPENAIR_DIR}/executables/nr-softmodem.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${OPENAIR2_DIR}/RRC/NAS/nas_config.c - ${OPENAIR2_DIR}/RRC/NAS/rb_config.c - ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c - ${OPENAIR_DIR}/common/utils/utils.c - ${OPENAIR_DIR}/common/utils/system.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${GTPU_need_ITTI} - ${XFORMS_SOURCE_NR} - ${T_SOURCE} - ${CONFIG_SOURCES} - ${SHLIB_LOADER_SOURCES} - ) - -target_link_libraries (nr-softmodem-nos1 - -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA - ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} - RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2 L2_NR MAC_NR_COMMON - NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB - -Wl,--end-group z dl) - -target_link_libraries (nr-softmodem-nos1 ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) -target_link_libraries (nr-softmodem-nos1 ${LIB_LMS_LIBRARIES}) -target_link_libraries (nr-softmodem-nos1 ${T_LIB}) - # nr-uesoftmodem is UE implementation ####################################### @@ -2483,6 +2469,7 @@ add_executable(nr-uesoftmodem ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_mac_common.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c @@ -2507,38 +2494,6 @@ target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${C target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-uesoftmodem ${T_LIB}) -# nr-uesoftmodem-nos1 -####################################### - -add_executable(nr-uesoftmodem-nos1 - ${rrc_h} - ${s1ap_h} -# ${OPENAIR_BIN_DIR}/messages_xml.h - ${OPENAIR_DIR}/executables/nr-ue.c - ${OPENAIR_DIR}/executables/nr-uesoftmodem.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c - ${OPENAIR_DIR}/common/utils/utils.c - ${OPENAIR_DIR}/common/utils/system.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${XFORMS_SOURCE_NR} - ${T_SOURCE} - ${CONFIG_SOURCES} - ${SHLIB_LOADER_SOURCES} - ) - -target_link_libraries (nr-uesoftmodem-nos1 - -Wl,--start-group - RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB PHY_COMMON PHY_NR_COMMON PHY_NR_UE PHY_UE PHY_RU LFDS NR_L2_UE MAC_NR_COMMON - ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} - -Wl,--end-group z dl) - -target_link_libraries (nr-uesoftmodem-nos1 ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-uesoftmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) -target_link_libraries (nr-uesoftmodem-nos1 ${LIB_LMS_LIBRARIES}) -target_link_libraries (nr-uesoftmodem-nos1 ${T_LIB}) - # USIM process ################# @@ -2586,37 +2541,64 @@ target_link_libraries (dlsim_tm4 add_executable(polartest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c ${OPENAIR_DIR}/common/utils/backtrace.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c) -target_link_libraries(polartest SIMU PHY PHY_NR PHY_COMMON PHY_NR_COMMON m ${ATLAS_LIBRARIES}) + ${OPENAIR_DIR}/common/utils/nr/nr_common.c + ${OPENAIR_DIR}/common/utils/system.c + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(polartest + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE CONFIG_LIB -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} dl + ) - -add_executable(smallblocktest +add_executable(smallblocktest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/smallblocktest.c ${OPENAIR_DIR}/common/utils/backtrace.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c) -target_link_libraries(smallblocktest SIMU PHY PHY_NR PHY_COMMON PHY_NR_COMMON m ${ATLAS_LIBRARIES}) + ${OPENAIR_DIR}/common/utils/nr/nr_common.c + ${OPENAIR_DIR}/common/utils/system.c + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} +) + + +target_link_libraries(smallblocktest + -Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} dl + ) add_executable(ldpctest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c - ${OPENAIR_DIR}/common/utils/backtrace.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c) -target_link_libraries(ldpctest SIMU PHY PHY_NR m ${ATLAS_LIBRARIES}) + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(ldpctest + -Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} dl + ) add_executable(nr_dlschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c - ${OPENAIR_DIR}/common/utils/backtrace.c ${OPENAIR_DIR}/common/utils/system.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${T_SOURCE}) - target_link_libraries(nr_dlschsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl) + ${UTIL_SRC} + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(nr_dlschsim + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl + ) add_executable(nr_pbchsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c - ${OPENAIR_DIR}/common/utils/backtrace.c ${OPENAIR_DIR}/common/utils/system.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${T_SOURCE}) -target_link_libraries(nr_pbchsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} $(ITTI_LIB) dl) + ${UTIL_SRC} + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(nr_pbchsim + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl + ) #PUCCH ---> Prashanth add_executable(nr_pucchsim @@ -2625,45 +2607,63 @@ add_executable(nr_pucchsim ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/system.c ${UTIL_SRC} - ${T_SOURCE}) -target_link_libraries(nr_pucchsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(nr_pucchsim + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl + ) #PUCCH ---> Prashanth add_executable(nr_dlsim - ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c - ${OPENAIR_DIR}/common/utils/backtrace.c + ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${UTIL_SRC} - ${T_SOURCE}) -target_link_libraries(nr_dlsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(nr_dlsim + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl + ) add_executable(nr_prachsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/prachsim.c - ${OPENAIR_DIR}/common/utils/backtrace.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c - ${T_SOURCE}) -target_link_libraries(nr_prachsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl) + ${UTIL_SRC} + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES}) +target_link_libraries(nr_prachsim + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) add_executable(nr_ulschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c - ${OPENAIR_DIR}/common/utils/backtrace.c ${OPENAIR_DIR}/common/utils/system.c ${UTIL_SRC} - ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${T_SOURCE}) -target_link_libraries(nr_ulschsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(nr_ulschsim + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl + ) add_executable(nr_ulsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulsim.c - ${OPENAIR_DIR}/common/utils/backtrace.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/system.c + ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${UTIL_SRC} - ${T_SOURCE}) -target_link_libraries(nr_ulsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(nr_ulsim + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl + ) foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim) @@ -2744,10 +2744,10 @@ endforeach(myExe) if (${T_TRACER}) foreach(i #all "add_executable" definitions (except tests, rb_tool, updatefw) - lte-softmodem lte-uesoftmodem nr-softmodem nr-softmodem-nos1 - nr-uesoftmodem nr-uesoftmodem-nos1 dlsim dlsim_tm4 dlsim_tm7 + lte-softmodem lte-uesoftmodem nr-softmodem + nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim - syncsim ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim + syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim nr_ulschsim ldpctest polartest smallblocktest cu_test du_test #all "add_library" definitions @@ -2758,7 +2758,7 @@ if (${T_TRACER}) SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX - L2 L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR CN_UTILS GTPV1U + L2 L2_LTE L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR CN_UTILS GTPV1U SCTP_CLIENT UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU SIMU_ETH OPENAIR0_LIB) if (TARGET ${i}) add_dependencies(${i} generate_T) diff --git a/cmake_targets/autotests/README.txt b/cmake_targets/autotests/README.txt index b94d99bff7..10c14fd59a 100644 --- a/cmake_targets/autotests/README.txt +++ b/cmake_targets/autotests/README.txt @@ -96,11 +96,41 @@ Obj.# Case# Test# Description (Test 4, 10 MHz, R3-1.FDD (MCS 16), AWGN, 12dB (70%)), (Test 5, 20 MHz, FDD (MCS 5), AWGN, 6dB (70%)), (Test 6, 20 MHz, FDD (MCS 16), AWGN, 12 dB (70%)) -01 51 02 pucchsim (TBD) -01 51 03 prachsim (TBD) -01 51 04 pdcchsim (TBD) -01 51 05 pbchsim (TBD) -01 51 06 mbmssim (TBD) +01 51 02 ldpc Test cases. (Test1: block length = 3872), + (Test2: block length = 4224), + (Test3: block length = 4576), + (Test4: block length = 4928), + (Test5: block length = 5280), + (Test6: block length = 5632), + (Test7: block length = 6336), + (Test8: block length = 7040), + (Test9: block length = 7744), + (Test10: block length = 8448) +01 51 03 polartest Test cases. (Test1: PBCH polar test), + (Test2: DCI polar test) +01 51 04 nr_pbchsim Test cases. (Test1: PBCH-only, 106 PRB), + (Test2: PBCH and synchronization, 106PBR), + (Test3: PBCH-only, 217 PRB), + (Test4: PBCH and synchronization, 217 RPB), + (Test5: PBCH-only, 273 PRB), + (Test6: PBCH and synchronization, 273 PRB) +01 51 05 nr_dlsim Test cases. (Test1: 106 PRB), + (Test2: 217 PRB), + (Test3: 273 PRB) +01 51 06 nr_dlschsim Test cases. (Test1: 106 PRB), + (Test2: 217 PRB), + (Test3: 273 PRB) +01 51 07 shortblocktest Test cases. (Test1: 3 bits), + (Test2: 6 bits), + (Test3: 7 bits), + (Test4: 11 bits) +01 51 08 nr_ulschsim Test cases. (Test1: 106 PRB), + (Test2: 217 PRB), + (Test3: 273 PRB) +01 51 09 nr_pucchsim Test cases. (Test1: Format 0 ACK miss 106 PRB), + (Test2: Format 1 ACK miss 106 PRB), + (Test3: Format 1 ACK miss 273 PRB), + (Test4: Format 1 NACKtoACK 106 PRB) 01 51 10 dlsim_tm4 test cases (Test 1: 10 MHz, R2.FDD (MCS 5), EVA5, -1dB), (Test 5: 1.4 MHz, R4.FDD (MCS 4), EVA5, 0dB (70%)), (Test 6: 10 MHz, R3.FDD (MCS 15), EVA5, 6.7dB (70%)), @@ -110,8 +140,11 @@ Obj.# Case# Test# Description (Test 10: 5 MHz, R6.FDD (MCS 25), EVA5, 17.4 dB (70%)), (Test 10b: 5 MHz, R6-1.FDD (MCS 24,18 PRB), EVA5, 17.5dB (70%)), (Test 11: 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%)) - (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)), - (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)), + (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)), + (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)), +01 51 11 nr_ulsim Test cases. (Test1: MCS 9), + (Test2: MCS 16), + (Test3: MCS 28) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index d30537424b..6795f2d1fa 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1081,18 +1081,35 @@Terminate_FlexranCtrl +Stopping Flexran Controller +execution nr_dlsim Test cases. (Test1: 106 PRB), (Test2: 217 PRB), - (Test3: 273 PRB) + (Test3: 273 PRB), + (Test4: 106 PRB 12 CSET-Offset), + (Test5: 217 PRB 48 CSET-Offset), + (Test6: 106 PRB 25 PDSCH-Offset), + (Test7: 106 PRB 51 PDSCH-Offset), + (Test8: 217 PRB 100 PDSCH-PRBs), + (Test9: 217 PRB 80 PDSCH-Offset), + (Test10: 217 PRB 100 PDSCH-PRBs 110 PDSCH-Offset), + (Test11: 106 PRBs 50 PDSCH-PRBs MCS Index 28$OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash $OPENAIR_DIR/targets/bin/nr_dlsim.Rel15 --n100 -R106 - -n100 -R217 - -n100 -R273 -nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 -PDCCH test OK +-n100 -R106 -b106 + -n100 -R217 -b217 + -n100 -R273 -b273 + -n100 -R106 -o12 + -n100 -R217 -o48 + -n100 -R106 -a25 + -n100 -R106 -a51 + -n100 -R217 -b100 + -n100 -R217 -a80 + -n100 -R217 -a110 -b100 + -n100 -e28 +nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 + nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 +PDSCH test OK segmentation fault|assertion|exiting|fatal 3 @@ -1220,6 +1237,30 @@3 ++ +execution +nr_ulsim Test cases. (Test1: MCS 9 106 PRBs), + (Test2: MCS 16 50 PRBs), + (Test3: MCS 28 50 PRBs), + (Test4: MCS 9 217 PRBs), + (Test5: MCS 9 273 PRBs) ++ $OPENAIR_DIR/cmake_targets/build_oai +--phy_simulators -c +$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash ++ $OPENAIR_DIR/targets/bin/nr_ulsim.Rel15 +-f100 -m9 -r106 -s10 + -f100 -m16 -s20 + -f100 -m28 -s30 + -f100 -m9 -R217 -r217 -s10 + -f100 -m9 -R273 -r273 -s10 +nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 +PUSCH test OK +segmentation fault|assertion|exiting|fatal +3 +lte-softmodem diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 220cd40c93..677095d43a 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -149,7 +149,7 @@ Options --build-eclipse Build eclipse project files. Paths are auto corrected by fixprj.sh --build-lib - Build optional shared library, can be one or several of $OPTIONAL_LIBRARIES + Build optional shared library, can be one or several of $OPTIONAL_LIBRARIES or \"all\" --usrp-recplay Build for I/Q record-playback modes -h | --help @@ -346,16 +346,21 @@ function main() { shift 1;; --build-lib) BUILD_OPTLIB="" - for alib in $2 ; do + if [ "$2" == "all" ] ; then + BUILD_OPTLIB="$OPTIONAL_LIBRARIES" + echo_info "Enabling build of all optional shared libraries ($OPTIONAL_LIBRARIES)" + else + for alib in $2 ; do for oklib in $OPTIONAL_LIBRARIES ; do - if [ "$alib" = "$oklib" ] ; then - BUILD_OPTLIB="$BUILD_OPTLIB $alib" - echo_info "Enabling build of lib${alib}.so" - fi + if [ "$alib" = "$oklib" ] ; then + BUILD_OPTLIB="$BUILD_OPTLIB $alib" + echo_info "Enabling build of lib${alib}.so" + fi + done done - done - if [ "${BUILD_OPTLIB## }" != "$2" ] ; then - echo_fatal "Unknown optional library in $2, valid libraries are $OPTIONAL_LIBRARIES" + if [ "${BUILD_OPTLIB## }" != "$2" ] ; then + echo_fatal "Unknown optional library in $2, valid libraries are $OPTIONAL_LIBRARIES" + fi fi shift 2;; --usrp-recplay) @@ -580,7 +585,8 @@ function main() { nr-uesoftmodem $dbin/nr-uesoftmodem.$REL fi -# mandatory shared lib +# mandatory shared libraries common to UE and (e/g)NB + compilations \ $build_dir $config_libconfig_shlib \ lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so @@ -864,7 +870,6 @@ function main() { ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so echo_info "liboai_transpro.so is linked to ETHERNET transport" fi - ################### # Doxygen Support # diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 4af81a1a22..99a2e3f589 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -103,6 +103,7 @@ check_supported_distribution() { "fedora24") return 0 ;; "rhel7") return 0 ;; "rhel7.6") return 0 ;; + "rhel7.7") return 0 ;; "centos7") return 0 ;; esac return 1 diff --git a/common/config/DOC/config/devusage/api.md b/common/config/DOC/config/devusage/api.md index 06c22dba6f..376e59abaf 100644 --- a/common/config/DOC/config/devusage/api.md +++ b/common/config/DOC/config/devusage/api.md @@ -1,3 +1,5 @@ +## config module management + ```c configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t initflags) ``` @@ -14,23 +16,17 @@ void End_configmodule(void) * Free memory which has been allocated by the configuration module since its initialization. * Possibly calls the `config_ _end` function +## Retrieving parameter's values + ```c int config_get(paramdef_t *params,int numparams, char *prefix) ``` * Reads as many parameters as described in params, they must all be in the same configuration file section * Calls the `config_ _get` function * Calls the `config_process_cmdline` function -* `params` points to an array of `paramdef_t` structures which describes the parameters to be read, possibly including a pointer to a checking function. The following bits can possibly be set in the `paramflags` mask before calling - - `PARAMFLAG_MANDATORY`: -1 is returned if the parameter is not explicitly defined in the config source. - - `PARAMFLAG_DISABLECMDLINE`: parameter cannot be modified via the command line - - `PARAMFLAG_DONOTREAD`: ignore the parameter, can be used at run-time, to alter a pre-defined `paramdef_t` array which is used in several `config_get` or/and `config_getlist` calls. - - `PARAMFLAG_NOFREE`: do not free the memory possibly allocated by the config module to store the value of the parameter. Default behavior is for the config module to free the memory it has allocated when the `config_end` function is called. - - `PARAMFLAG_BOOL`: Only relevant for integer types. tell the config module that when processing the command line, the corresponding option can be specified without any arggument and that in this case it must set the value to 1. +* `params` points to an array of `paramdef_t` structures which describes the parameters to be read, possibly including a pointer to a checking function.The `paramflags` bit mask can be used to modify how a specific parameter is processed and the same mask is also used by the configuration module to return information about how the parameter has been processed. Bits definitions are described in the [`paramdef_t` structure description](./struct.md) + -* `params` is also used as an output parameter, `< XXX >ptr >` field is used by the config module to store the value it has read. The following bits can possibly be set in the `paramflags` mask after the call: - - `PARAMFLAG_MALLOCINCONFIG`: memory has been allocated for the ` < XXX >ptr > ` field - - `PARAMFLAG_PARAMSET`: parameter has been found in the config source, it is not set to default value. - - `PARAMFLAG_PARAMSET`: parameter has been set to its default value * `numparams` is the number of entries in the params array * `prefix` is a character string to be appended to the parameters name, it defines the parameters position in the configuration file hierarchy (the section name in libconfig terminology). * The returned value is the number of parameters which have been assigned a value or -1 if a severe error occured @@ -44,6 +40,9 @@ int config_libconfig_getlist(paramlist_def_t *ParamList, paramdef_t *params, int * `ParamList` points to a structure, where `paramarray` field points to an array of `paramdef_t` structure, allocated by the function. It is used to return the values of the parameters. * The returned value is the number of occurrences in the list or -1 in case of severe error +## utility functions and macros + +The configuration module also defines APIs to access the `paramdef_t` and `configmodule_interface_t` fields. They are listed in the configuration module [include file `common/config/config_userapi.h`](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_userapi.h) [Configuration module developer main page](../../config/devusage.md) [Configuration module home](../../config.md) diff --git a/common/config/DOC/config/devusage/struct.md b/common/config/DOC/config/devusage/struct.md index e8b15fc0f1..4c9cd15785 100644 --- a/common/config/DOC/config/devusage/struct.md +++ b/common/config/DOC/config/devusage/struct.md @@ -5,6 +5,7 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla |:-----------|:------------------------------------------------------------------|----:| | `optname` | parameter name, as used when looking for it in the config source, 63 bytes max (64 with trailing \0) | I | | `helstr` | pointer to a C string printed when using --help on the command line | I | +| `paramflags` | bit mask, used to modify how the parameter is processed, or to return to the API caller how the parameter has been set, see list in the next table | IO | | `strptr` `strlistptr` `u8ptr` `i8ptr` `u16ptr` `i16ptr` `uptr` `iptr` `u64ptr` `i64ptr` `dblptr` `voidptr` | a pointer to a variable where the parameter value(s) will be returned. This field is an anonymous union, the supported pointer types have been built to avoid type mismatch warnings at compile time. | O | | `defstrval` `defstrlistval` `defuintval` `defintval` `defint64val` `defintarrayval` `defdblval` | this field is an anonymous union, it can be used to define the default value for the parameter. It is ignored if `PARAMFLAG_MANDATORY` is set in the `paramflags` field.| I | | `type` | Supported parameter types are defined as integer macros. Supported simple types are `TYPE_STRING`, parameter value is returned in `strptr` field, `TYPE_INT8` `TYPE_UINT8` `TYPE_INT16` `TYPE_UINT16` `TYPE_INT32` `TYPE_UINT32` `TYPE_INT64` `TYPE_UINT64`, parameter value is returned in the corresponding uXptr or iXptr, `TYPE_MASK`, value is returned in `u32ptr`, `TYPE_DOUBLE` value is returned in `dblptr`, `TYPE_IPV4ADDR` value is returned in binary, network bytes order in `u32ptr` field. `TYPE_STRINGLIST`, `TYPE_INTARRAY` and `TYPE_UINTARRAY` are multiple values types. Multiple values are returned in respectively, `strlistptr`, `iptr` and `uptr` fields which then point to arrays. The `numelt` field gives the number of item in the array. | I | @@ -12,6 +13,22 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla | `chkPptr` | possible pointer to the structure containing the info used to check parameter values | I | | `processedvalue` | When `chkPptr` is not `ǸULL`, is used to return a value, computed from the original parameter, as read from the configuration source. | O | +## `paramflags` bits definition + + +| C macro bit definition | usage | I/O | +|:-------------------------------------|:---------------------------------------------------------------------------------------------------------------------|----:| +| `PARAMFLAG_MANDATORY` | parameter is mandatory, comfiguration module will stop the process if it is not specified. Default value is ignored | I | +| `PARAMFLAG_DISABLECMDLINE` | parameter cannot be specified on the command line | I | +| `PARAMFLAG_DONOTREAD` | ignore the parameter, usefull when a parameter group is used in different context | I | +| `PARAMFLAG_NOFREE` | The end_configmodule API won't free the memory which has been possibly allocated to store the value of the parameter.| I | +| `PARAMFLAG_BOOL` | Parameter is a boolean, it can be specified without a value to set it to true | I | +| `PARAMFLAG_CMDLINE_NOPREFIXENABLED` | parameter can be specified without the prefix on the command line. Must be used with care, carefuly checking unicity, especially for short parameter names | I | +| `PARAMFLAG_MALLOCINCONFIG` | Memory for the parameter value has been allocated by the configuration module |O | +| `PARAMFLAG_PARAMSET` | Parameter value has been explicitely set, as the parameter was specified either on the command line or the config source | O | +| `PARAMFLAG_PARAMSETDEF` | Parameter value has been set to it's default | O | + + # `paramlist_def_t`structure It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L160). It is used as an argument to `config_getlist` calls, to get values of multiple occurrences of group of parameters. diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c index 249765a46e..6d01d98c65 100644 --- a/common/config/config_cmdline.c +++ b/common/config/config_cmdline.c @@ -167,8 +167,8 @@ int config_check_unknown_cmdlineopt(char *prefix) { char testprefix[CONFIG_MAXOPTLENGTH]; int finalcheck = 0; memset(testprefix,0,sizeof(testprefix)); - memset(testprefix,0,sizeof(testprefix)); + if (prefix != NULL) { if (strcmp(prefix,CONFIG_CHECKALLSECTIONS) == 0) finalcheck = 1; @@ -253,7 +253,9 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) } if ( ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgpath) == 0)) || /* short option, one "-" */ - ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) ) { + ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) || /* long option beginning with "--" */ + ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgoptions[n].optname) == 0) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) || + ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 ) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ) { char *valptr=NULL; int ret; config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED; diff --git a/common/config/config_paramdesc.h b/common/config/config_paramdesc.h index 9aad79960d..86fc993a08 100644 --- a/common/config/config_paramdesc.h +++ b/common/config/config_paramdesc.h @@ -45,7 +45,7 @@ #define PARAMFLAG_DONOTREAD (1 << 2) // parameter must be ignored in get function #define PARAMFLAG_NOFREE (1 << 3) // don't free parameter in end function #define PARAMFLAG_BOOL (1 << 4) // integer param can be 0 or 1 - +#define PARAMFLAG_CMDLINE_NOPREFIXENABLED (1 << 5) // on the command line, allow a parameter to be specified without the prefix /* Flags used by config modules to return info to calling modules and/or to for internal usage*/ #define PARAMFLAG_MALLOCINCONFIG (1 << 15) // parameter allocated in config module diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index bf0ae01cf7..cbb0d4c0a7 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -81,7 +81,7 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) { } if (*ptr == NULL) { - *ptr = malloc(length); + *ptr = malloc(length>40?length:40); // LTS: dummy fix, waiting Francois full fix in 4G branch if ( *ptr != NULL) { memset(*ptr,0,length); @@ -172,7 +172,7 @@ int config_get_processedint(paramdef_t *cfgoption) { return ret; } void config_printhelp(paramdef_t *params,int numparams, char *prefix) { - printf("\n-----Help for section %-26s: %03i entries------\n",(prefix==NULL)?"(root section)":prefix ,numparams); + printf("\n-----Help for section %-26s: %03i entries------\n",(prefix==NULL)?"(root section)":prefix,numparams); for (int i=0 ; i numelt == 0 ) { - config_check_valptr(cfgoptions, (char **)(cfgoptions->strptr), sizeof(char *)); config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(cfgoptions->defstrval)+1); sprintf(*(cfgoptions->strptr), "%s",cfgoptions->defstrval); printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, *(cfgoptions->strptr)); } else { - sprintf((char *)*(cfgoptions->strptr), "%s",cfgoptions->defstrval); - printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (char *)*(cfgoptions->strptr)); + sprintf((char *)(cfgoptions->strptr), "%s",cfgoptions->defstrval); + printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (char *)(cfgoptions->strptr)); } } @@ -437,7 +446,7 @@ int config_setdefault_intlist(paramdef_t *cfgoptions, char *prefix) { status=1; for (int j=0; j numelt ; j++) { - printf_params("[CONFIG] %s[%i] set to default value %i\n",cfgoptions->optname ,j,(int)cfgoptions->iptr[j]); + printf_params("[CONFIG] %s[%i] set to default value %i\n",cfgoptions->optname,j,(int)cfgoptions->iptr[j]); } } @@ -451,7 +460,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) { if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) { *(cfgoptions->dblptr)=cfgoptions->defdblval; status=1; - printf_params("[CONFIG] %s set to default value %lf\n",cfgoptions->optname , *(cfgoptions->dblptr)); + printf_params("[CONFIG] %s set to default value %lf\n",cfgoptions->optname, *(cfgoptions->dblptr)); } return status; @@ -459,7 +468,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) { int config_assign_ipv4addr(paramdef_t *cfgoptions, char *ipv4addr) { config_check_valptr(cfgoptions,(char **)&(cfgoptions->uptr), sizeof(int)); - int rst=inet_pton(AF_INET, ipv4addr ,cfgoptions->uptr ); + int rst=inet_pton(AF_INET, ipv4addr,cfgoptions->uptr ); if (rst == 1 && *(cfgoptions->uptr) > 0) { printf_params("[CONFIG] %s: %s\n",cfgoptions->optname, ipv4addr); diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h index cc07b1af5f..c00526aa4c 100644 --- a/common/config/config_userapi.h +++ b/common/config/config_userapi.h @@ -39,6 +39,7 @@ extern "C" { #endif +/* utility functions to ease usage of config module structures */ #define CONFIG_GETSOURCE ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode ) #define CONFIG_GETNUMP ( (config_get_if()==NULL) ? 0 : config_get_if()->num_cfgP ) #define CONFIG_GETP(P) ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgP[P] ) @@ -46,6 +47,8 @@ extern "C" #define CONFIG_SETRTFLAG(P) if (config_get_if()) { config_get_if()->rtflags |= P; } #define CONFIG_CLEARRTFLAG(P) if (config_get_if()) { config_get_if()->rtflags &= (~P); } #define CONFIG_ISPARAMFLAGSET(P,F) ( !!(P.paramflags & F)) +extern int config_paramidx_fromname(paramdef_t *params,int numparams, char *name); + /* utility functions, to be used by configuration module and/or configuration libraries */ extern configmodule_interface_t *config_get_if(void); extern char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ; diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 1108eb46da..7f177b90ce 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -232,7 +232,7 @@ int write_file_matlab(const char *fname, void log_getconfig(log_t *g_log) { char *gloglevel = NULL; - int consolelog ; + int consolelog = 0; paramdef_t logparams_defaults[] = LOG_GLOBALPARAMS_DESC; paramdef_t logparams_level[MAX_LOG_PREDEF_COMPONENTS]; paramdef_t logparams_logfile[MAX_LOG_PREDEF_COMPONENTS]; @@ -324,7 +324,9 @@ void log_getconfig(log_t *g_log) config_get( logparams_debug,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX); config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX); - config_check_unknown_cmdlineopt(CONFIG_STRING_LOG_PREFIX); + + if (config_check_unknown_cmdlineopt(CONFIG_STRING_LOG_PREFIX) > 0) + exit(1); /* set the debug mask according to the debug parameters values */ for (int i=0; log_maskmap[i].name != NULL ; i++) { @@ -434,6 +436,10 @@ int logInit (void) register_log_component("ASN","log",ASN); register_log_component("NFAPI_VNF","log",NFAPI_VNF); register_log_component("NFAPI_PNF","log",NFAPI_PNF); + register_log_component("GNB_APP","log",GNB_APP); + register_log_component("NR_RRC","log",NR_RRC); + register_log_component("NR_MAC","log",NR_MAC); + register_log_component("NR_PHY","log",NR_PHY); for (int i=0 ; log_level_names[i].name != NULL ; i++) g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index cee14a27af..111f2c58ce 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -25,7 +25,6 @@ * \date 2009 - 2014 * \version 0.5 * @ingroup util - */ #ifndef __LOG_H__ @@ -297,7 +296,7 @@ extern "C" { # include "log_if.h" /*----------------------------------------------------------------------------*/ int logInit (void); -int isLogInitDone (void); +int isLogInitDone (void); void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7))); void vlogRecord_mt(const char *file, const char *func, int line, int comp, int level, const char *format, va_list args ); void log_dump(int component, void *buffer, int buffsize,int datatype, const char *format, ... ); @@ -363,14 +362,14 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int -/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* LOG globalconfiguration parameters */ -/* optname help paramflags XXXptr defXXXval type numelt */ -/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* LOG globalconfiguration parameters */ +/* optname help paramflags XXXptr defXXXval type numelt */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define LOG_GLOBALPARAMS_DESC { \ - {LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all componemts\n", 0, strptr:(char **)&gloglevel, defstrval:log_level_names[2].name, TYPE_STRING, 0}, \ - {LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, iptr:&(consolelog), defintval:1, TYPE_INT, 0}, \ - {LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS, LOG_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0} \ + {LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all componemts\n", 0, strptr:(char **)&gloglevel, defstrval:log_level_names[2].name, TYPE_STRING, 0}, \ + {LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, iptr:&(consolelog), defintval:1, TYPE_INT, 0}, \ + {LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS, LOG_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0} \ } #define LOG_OPTIONS_IDX 2 diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index b3a1aaad07..63c5336bd8 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -247,7 +247,8 @@ const char* eurecomVariablesNames[] = { "slot_number_TX0_gNB", "slot_number_TX1_gNB", "slot_number_RX0_gNB", - "slot_number_RX1_gNB" + "slot_number_RX1_gNB", + "ru_tx_ofdm_mask" }; const char* eurecomFunctionsNames[] = { @@ -328,6 +329,13 @@ const char* eurecomFunctionsNames[] = { "phy_procedures_ru_feptx_ofdm7", "phy_procedures_ru_feptx_ofdm8", "phy_procedures_ru_feptx_ofdm9", + "phy_procedures_ru_feptx_ofdm10", + "phy_procedures_ru_feptx_ofdm11", + "phy_procedures_ru_feptx_ofdm12", + "phy_procedures_ru_feptx_ofdm13", + "phy_procedures_ru_feptx_ofdm14", + "phy_procedures_ru_feptx_ofdm15", + "phy_procedures_ru_feptx_ofdm16", "phy_procedures_ru_feptx_prec0", "phy_procedures_ru_feptx_prec1", "phy_procedures_ru_feptx_prec2", @@ -502,6 +510,7 @@ const char* eurecomFunctionsNames[] = { "pdcch_interleaving", "pdcch_tx", /*NR softmodem signal*/ + "wakeup_txfh", "gNB_thread_rxtx0", "gNB_thread_rxtx1" }; @@ -634,7 +643,7 @@ void *vcd_dumper_thread_rt(void *args) uint32_t data_ready_wait; # if defined(ENABLE_ITTI) - signal_mask(); + return 0; //signal_mask(); //function defined at common/utils/ocp_itti/intertask_interface.cpp # endif sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 1; diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index a7c4c10fe3..3a6fb6d6ab 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -225,6 +225,7 @@ typedef enum { VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB, VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB, VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX1_GNB, + VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, VCD_SIGNAL_DUMPER_VARIABLES_END @@ -309,6 +310,13 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM7, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM8, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM9, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM10, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM11, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM12, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM13, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM14, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM15, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM16, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC1, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC2, @@ -494,6 +502,7 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX, /*NR softmodem signal*/ + VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 4f2b10c3ae..ab275d4d62 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -73,10 +73,10 @@ typedef struct { } T_cache_t; /* number of VCD functions (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_FUNCTIONS (237)//(232) +#define VCD_NUM_FUNCTIONS (245) /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_VARIABLES (185) +#define VCD_NUM_VARIABLES (186) /* first VCD function (to be kept up to date! see in T_messages.txt) */ #define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 0b10b6e25e..407bb66be1 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -2050,6 +2050,11 @@ ID = VCD_VARIABLE_SLOT_NUMBER_RX1_GNB GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value VCD_NAME = slot_number_RX1_gNB +ID = VCD_VARIABLE_RU_TX_OFDM_MASK + DESC = VCD variable RU_TX_OFDM_MASK + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ru_tx_ofdm_mask #functions @@ -2418,6 +2423,41 @@ ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM9 GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value VCD_NAME = phy_procedures_ru_feptx_ofdm9 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM10 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM10 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm10 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM11 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM11 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm11 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM12 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM12 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm12 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM13 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM13 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm13 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM14 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM14 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm14 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM15 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM15 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm15 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM16 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM16 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm16 ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC GROUP = ALL:VCD:ENB:VCD_FUNCTION @@ -3230,6 +3270,11 @@ ID = VCD_FUNCTION_PDCCH_TX VCD_NAME = pdcch_tx #function for gNB +ID = VCD_FUNCTION_WAKEUP_TXFH + DESC = VCD function WAKEUP_TXFH + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = wakeup_txfh ID = VCD_FUNCTION_gNB_PROC_RXTX0 DESC = VCD function gNB_PROC_RXTX0 GROUP = ALL:VCD:ENB:VCD_FUNCTION diff --git a/common/utils/hashtable/hashtable.c b/common/utils/hashtable/hashtable.c index 50c2ec8324..e9641f8e0c 100644 --- a/common/utils/hashtable/hashtable.c +++ b/common/utils/hashtable/hashtable.c @@ -162,34 +162,6 @@ hashtable_rc_t hashtable_is_key_exists (const hash_table_t *const hashtblP, cons return HASH_TABLE_KEY_NOT_EXISTS; } //------------------------------------------------------------------------------------------------------------------------------- -hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *const hashtblP, void functP(hash_key_t keyP, void *dataP, void *parameterP), void *parameterP) -//------------------------------------------------------------------------------------------------------------------------------- -{ - hash_node_t *node = NULL; - unsigned int i = 0; - unsigned int num_elements = 0; - - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - - while ((num_elements < hashtblP->num_elements) && (i < hashtblP->size)) { - if (hashtblP->nodes[i] != NULL) { - node=hashtblP->nodes[i]; - - while(node) { - num_elements += 1; - functP(node->key, node->data, parameterP); - node=node->next; - } - } - - i += 1; - } - - return HASH_TABLE_OK; -} -//------------------------------------------------------------------------------------------------------------------------------- hashtable_rc_t hashtable_dump_content (const hash_table_t *const hashtblP, char *const buffer_pP, int *const remaining_bytes_in_buffer_pP ) //------------------------------------------------------------------------------------------------------------------------------- { @@ -266,7 +238,6 @@ hashtable_rc_t hashtable_insert(hash_table_t *const hashtblP, const hash_key_t k } hashtblP->nodes[hash]=node; - hashtblP->num_elements += 1; return HASH_TABLE_OK; } //------------------------------------------------------------------------------------------------------------------------------- @@ -295,7 +266,6 @@ hashtable_rc_t hashtable_remove(hash_table_t *const hashtblP, const hash_key_t k } free(node); - hashtblP->num_elements -= 1; return HASH_TABLE_OK; } @@ -335,47 +305,3 @@ hashtable_rc_t hashtable_get(const hash_table_t *const hashtblP, const hash_key_ *dataP = NULL; return HASH_TABLE_KEY_NOT_EXISTS; } -//------------------------------------------------------------------------------------------------------------------------------- -/* - * Resizing - * The number of elements in a hash table is not always known when creating the table. - * If the number of elements grows too large, it will seriously reduce the performance of most hash table operations. - * If the number of elements are reduced, the hash table will waste memory. That is why we provide a function for resizing the table. - * Resizing a hash table is not as easy as a realloc(). All hash values must be recalculated and each element must be inserted into its new position. - * We create a temporary hash_table_t object (newtbl) to be used while building the new hashes. - * This allows us to reuse hashtable_insert() and hashtable_remove(), when moving the elements to the new table. - * After that, we can just free the old table and copy the elements from newtbl to hashtbl. - */ - -hashtable_rc_t hashtable_resize(hash_table_t *const hashtblP, const hash_size_t sizeP) { - hash_table_t newtbl; - hash_size_t n; - hash_node_t *node,*next; - - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - - newtbl.size = sizeP; - newtbl.hashfunc = hashtblP->hashfunc; - newtbl.num_elements = 0; - - if(!(newtbl.nodes=calloc(sizeP, sizeof(hash_node_t *)))) return -1; - - for(n=0; n size; ++n) { - for(node=hashtblP->nodes[n]; node; node=next) { - next = node->next; - hashtable_insert(&newtbl, node->key, node->data); - // Lionel GAUTHIER: BAD CODE TO BE REWRITTEN - hashtable_remove(hashtblP, node->key); - } - } - - free(hashtblP->nodes); - hashtblP->size=newtbl.size; - hashtblP->nodes=newtbl.nodes; - return HASH_TABLE_OK; -} - - - diff --git a/common/utils/hashtable/hashtable.h b/common/utils/hashtable/hashtable.h index 3f770684fa..09f8623ce2 100644 --- a/common/utils/hashtable/hashtable.h +++ b/common/utils/hashtable/hashtable.h @@ -49,7 +49,6 @@ typedef struct hash_node_s { typedef struct hash_table_s { hash_size_t size; - hash_size_t num_elements; struct hash_node_s **nodes; hash_size_t (*hashfunc)(const hash_key_t); void (*freefunc)(void *); @@ -60,12 +59,10 @@ void hash_free_int_func(void *memoryP); hash_table_t *hashtable_create (const hash_size_t size, hash_size_t (*hashfunc)(const hash_key_t ), void (*freefunc)(void *)); hashtable_rc_t hashtable_destroy(hash_table_t **hashtbl); hashtable_rc_t hashtable_is_key_exists (const hash_table_t *const hashtbl, const uint64_t key); -hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *const hashtblP, void funct(hash_key_t keyP, void *dataP, void *parameterP), void *parameterP); hashtable_rc_t hashtable_dump_content (const hash_table_t *const hashtblP, char *const buffer_pP, int *const remaining_bytes_in_buffer_pP ); hashtable_rc_t hashtable_insert (hash_table_t *const hashtbl, const hash_key_t key, void *data); hashtable_rc_t hashtable_remove (hash_table_t *const hashtbl, const hash_key_t key); hashtable_rc_t hashtable_get (const hash_table_t *const hashtbl, const hash_key_t key, void **dataP); -hashtable_rc_t hashtable_resize (hash_table_t *const hashtbl, const hash_size_t size); diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 484cd8aa26..cdbf59cd76 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -37,8 +37,8 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB) { int tmp = locationAndBandwidth/N_RB; int tmp2 = locationAndBandwidth%N_RB; - if (tmp <= (N_RB-tmp2+1)) return(tmp); - else return(N_RB-tmp); + if (tmp <= ((N_RB>>1)-tmp2+1)) return(tmp+1); + else return(N_RB+1-tmp); } @@ -46,17 +46,19 @@ int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB) { int tmp = locationAndBandwidth/N_RB; int tmp2 = locationAndBandwidth%N_RB; - if (tmp <= (N_RB-tmp2+1)) return(tmp2); - else return(N_RB-tmp2); + if (tmp <= ((N_RB>>1)-tmp2+1)) return(tmp2); + else return(N_RB-1-tmp2); +} + +int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize) { + AssertFatal(NPRB>0 && (NPRB + RBstart <= BWPsize),"Illegal NPRB/RBstart Configuration (%d,%d)\n",NPRB,RBstart); + if (NPRB <= 1+(BWPsize>>1)) return(BWPsize*(NPRB-1)+RBstart); + else return(BWPsize*(BWPsize+1-NPRB) + (BWPsize-1-RBstart)); } int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart) { - if (NPRB < 138) - return(275*(NPRB-1)+RBstart); - else - return(275*(276-NPRB) + (274-RBstart)); + return(PRBalloc_to_locationandbandwidth0(NPRB,RBstart,275)); } - /// Target code rate tables indexed by Imcs uint16_t nr_target_code_rate_table1[29] = {120, 157, 193, 251, 308, 379, 449, 526, 602, 679, 340, 378, 434, 490, 553, \ 616, 658, 438, 466, 517, 567, 616, 666, 719, 772, 822, 873, 910, 948}; @@ -128,3 +130,18 @@ int get_subband_size(int NPRB,int size) { AssertFatal(1==0,"Shouldn't get here, NPRB %d\n",NPRB); } + +void SLIV2SL(int SLIV,int *S,int *L) { + + int SLIVdiv14 = SLIV/14; + int SLIVmod14 = SLIV%14; + // Either SLIV = 14*(L-1) + S, or SLIV = 14*(14-L+1) + (14-1-S). Condition is 0 <= L <= 14-S + if ((SLIVdiv14 + 1) >= 0 && (SLIVdiv14 <= 13-SLIVmod14)) { + *L=SLIVdiv14+1; + *S=SLIVmod14; + } else { + *L=15-SLIVdiv14; + *S=13-SLIVmod14; + } + +} diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index c4ac58413e..979cf86343 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -35,6 +35,7 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB); int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB); +int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize); int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart); extern uint16_t nr_target_code_rate_table1[29]; extern uint16_t nr_target_code_rate_table2[28]; @@ -43,3 +44,22 @@ extern uint16_t nr_tbs_table[93]; uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx); uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx); int get_subband_size(int NPRB,int size); +void SLIV2SL(int SLIV,int *S,int *L); + + +#define CEILIDIV(a,b) ((a+b-1)/b) +#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) + +#define cmax(a,b) ((a>b) ? (a) : (b)) +#define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c)) +#define cmin(a,b) ((a typedef struct timer_elm_s { - timer_type_t type; ///< Timer type - long instance; + timer_type_t type; ///< Timer type + long instance; long duration; uint64_t timeout; - void *timer_arg; ///< Optional argument that will be passed when timer expires + void *timer_arg; ///< Optional argument that will be passed when timer expires } timer_elm_t ; typedef struct task_list_s { diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 868a9ba245..80493dc816 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -25,7 +25,7 @@ typedef struct { typedef struct { uint32_t interval_sec; uint32_t interval_us; - long task_id; + long task_id; int32_t instance; timer_type_t type; void *timer_arg; @@ -33,7 +33,7 @@ typedef struct { } timer_create_t; typedef struct { - long task_id; + long task_id; long timer_id; } timer_delete_t; @@ -536,6 +536,7 @@ int timer_setup( int timer_remove(long timer_id); #define timer_stop timer_remove int signal_handle(int *end); +int signal_mask(void); #ifdef __cplusplus } diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 7f8645be02..44ab07a49b 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -123,7 +123,7 @@ void client_printf(const char *message, ...) { if (telnetparams.new_socket > 0) { vsnprintf(telnetparams.msgbuff,sizeof(telnetparams.msgbuff)-1,message, va_args); - send(telnetparams.new_socket,telnetparams.msgbuff , strlen(telnetparams.msgbuff), MSG_NOSIGNAL); + send(telnetparams.new_socket,telnetparams.msgbuff, strlen(telnetparams.msgbuff), MSG_NOSIGNAL); } else { vprintf(message, va_args); } @@ -475,7 +475,7 @@ int process_command(char *buf) { memset(cmdb,0,sizeof(cmdb)); bufbck=strdup(buf); rt=CMDSTATUS_NOTFOUND; - j = sscanf(buf,"%9s %9s %9[^\t\n]",modulename,cmd,cmdb); + j = sscanf(buf,"%19s %19s %19[^\t\n]",modulename,cmd,cmdb); if (telnetparams.telnetdbg > 0) printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb); @@ -543,7 +543,7 @@ void run_telnetsrv(void) { char buf[TELNET_MAX_MSGLENGTH]; struct sockaddr cli_addr; unsigned int cli_len = sizeof(cli_addr); - int readc , filled; + int readc, filled; int status; int optval = 1; pthread_setname_np(pthread_self(), "telnet"); @@ -604,7 +604,7 @@ void run_telnetsrv(void) { } if (telnetparams.telnetdbg > 0) - printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled ,buf); + printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled,buf); if (buf[0] == '!') { if (buf[1] == '!') { diff --git a/common/utils/threadPool/Makefile b/common/utils/threadPool/Makefile index af0b44996c..6b28eb2ba8 100644 --- a/common/utils/threadPool/Makefile +++ b/common/utils/threadPool/Makefile @@ -1,8 +1,13 @@ -all: measurement_display thread-pool-test +all: +measurement_display thread-pool-test -measurement_display: measurement_display.c thread-pool.h - gcc measurement_display.c -I ${OPENAIR_DIR}/ -I ${OPENAIR_DIR}/common/utils/ -I. ${OPENAIR_DIR}/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o measurement_display +measurement_display: +measurement_display.c thread-pool.h +gcc measurement_display.c -I $ {OPENAIR_DIR}/ -I $ {OPENAIR_DIR}/common/utils/ -I. $ {OPENAIR_DIR}/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o +measurement_display -thread-pool-test: thread-pool.c thread-pool.h - gcc -g thread-pool.c -I ${OPENAIR_DIR}/ -I ${OPENAIR_DIR}/common/utils/ -I. ${OPENAIR_DIR}/common/utils/backtrace.c -I ${OPENAIR_DIR}/openair2/COMMON ${OPENAIR_DIR}/common/utils/LOG/log.c ${OPENAIR_DIR}/common/config/config_userapi.c ${OPENAIR_DIR}/common/config/config_load_configmodule.c ${OPENAIR_DIR}/common/config/config_cmdline.c -lpthread -ldl -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o thread-pool-test +thread-pool-test: +thread-pool.c thread-pool.h +gcc -g thread-pool.c -I $ {OPENAIR_DIR}/ -I $ {OPENAIR_DIR}/common/utils/ -I. $ {OPENAIR_DIR}/common/utils/backtrace.c -I $ {OPENAIR_DIR}/openair2/COMMON $ {OPENAIR_DIR}/common/utils/LOG/log.c $ {OPENAIR_DIR}/common/config/config_userapi.c +$ {OPENAIR_DIR}/common/config/config_load_configmodule.c $ {OPENAIR_DIR}/common/config/config_cmdline.c -lpthread -ldl -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o thread-pool-test diff --git a/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c index b45a8fa722..dd3d16d717 100644 --- a/common/utils/threadPool/thread-pool.c +++ b/common/utils/threadPool/thread-pool.c @@ -67,7 +67,7 @@ void *one_thread(void *arg) { delNotifiedFIFO_elt(elt); else pushNotifiedFIFO(elt->reponseFifo, elt); - + myThread->runningOnKey=-1; mutexunlock(tp->incomingFifo.lockF); } } while (true); @@ -95,7 +95,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { pool->nbThreads=0; pool->restrictRNTI=false; curptr=strtok_r(params,",",&saveptr); - + struct one_thread * ptr; while ( curptr!=NULL ) { int c=toupper(curptr[0]); @@ -109,8 +109,9 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { break; default: + ptr=pool->allthreads; pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread)); - pool->allthreads->next=pool->allthreads; + pool->allthreads->next=ptr; printf("create a thread for core %d\n", atoi(curptr)); pool->allthreads->coreID=atoi(curptr); pool->allthreads->id=pool->nbThreads; diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h index d6dc332c5a..9a2681a828 100644 --- a/common/utils/threadPool/thread-pool.h +++ b/common/utils/threadPool/thread-pool.h @@ -150,8 +150,9 @@ static inline notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf) { // This function aborts all messages matching the key // If the queue is used in thread pools, it doesn't cancels already running processing // because the message has already been picked -static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { +static inline int abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { mutexlock(nf->lockF); + int nbDeleted=0; notifiedFIFO_elt_t **start=&nf->outF; while(*start!=NULL) { @@ -159,13 +160,16 @@ static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { notifiedFIFO_elt_t *request=*start; *start=(*start)->next; delNotifiedFIFO_elt(request); - } - - if (*start != NULL) + nbDeleted++; + } else start=&(*start)->next; } + if (nf->outF == NULL) + nf->inF=NULL; + mutexunlock(nf->lockF); + return nbDeleted; } struct one_thread { @@ -195,7 +199,20 @@ typedef struct thread_pool { static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) { if (t->measurePerf) msg->creationTime=rdtsc(); - pushNotifiedFIFO(&t->incomingFifo, msg); + if ( t->activated) + pushNotifiedFIFO(&t->incomingFifo, msg); + else { + if (t->measurePerf) + msg->startProcessingTime=rdtsc(); + + msg->processingFunc(NotifiedFifoData(msg)); + + if (t->measurePerf) + msg->endProcessingTime=rdtsc(); + + if (msg->reponseFifo) + pushNotifiedFIFO(msg->reponseFifo, msg); + } } static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) { @@ -225,7 +242,8 @@ static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpo return msg; } -static inline void abortTpool(tpool_t *t, uint64_t key) { +static inline int abortTpool(tpool_t *t, uint64_t key) { + int nbRemoved=0; notifiedFIFO_t *nf=&t->incomingFifo; mutexlock(nf->lockF); notifiedFIFO_elt_t **start=&nf->outF; @@ -235,22 +253,27 @@ static inline void abortTpool(tpool_t *t, uint64_t key) { notifiedFIFO_elt_t *request=*start; *start=(*start)->next; delNotifiedFIFO_elt(request); - } - - if (*start != NULL) + nbRemoved++; + } else start=&(*start)->next; } + if (t->incomingFifo.outF==NULL) + t->incomingFifo.inF=NULL; + struct one_thread *ptr=t->allthreads; while(ptr!=NULL) { - if (ptr->runningOnKey==key) + if (ptr->runningOnKey==key) { ptr->abortFlag=true; + nbRemoved++; + } ptr=ptr->next; } mutexunlock(nf->lockF); + return nbRemoved; } void initTpool(char *params,tpool_t *pool, bool performanceMeas); diff --git a/common/utils/threadPool/thread-pool.md b/common/utils/threadPool/thread-pool.md index 2b6336fb60..bc1b1db54a 100644 --- a/common/utils/threadPool/thread-pool.md +++ b/common/utils/threadPool/thread-pool.md @@ -3,69 +3,90 @@ The thread pool is a working server, made of a set of worker threads that can be mapped on CPU cores. Each worker loop on pick from the same input queue jobs to do. + When a job is done, the worker sends a return if a return is defined. -A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless). + A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless). -All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter. + All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, + so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter. ## license -Author: Laurent Thomas, Open cells project -The owner share this piece code to Openairsoftware alliance as per OSA license terms + Author: + Laurent Thomas, Open cells project + The owner share this piece code to Openairsoftware alliance as per OSA license terms # jobs -A job is a message (notifiedFIFO_elt_t): -next: internal FIFO chain, do not set it -key: a long int that the client can use to identify a message or a group of messages -responseFifo: if the client defines a response FIFO, the message will be posted back after processing -processingFunc: any funtion (type void processingFunc(void *)) that the worker will launch -msgData: the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing -malloced: a boolean that enable internal free in these cases: no return Fifo or Abort feature + A job is a message (notifiedFIFO_elt_t): + next: + internal FIFO chain, do not set it + key: + a long int that the client can use to identify a message or a group of messages + responseFifo: + if the client defines a response FIFO, the message will be posted back after processing + processingFunc: + any funtion (type void processingFunc(void *)) that the worker will launch + msgData: + the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing + malloced: + a boolean that enable internal free in these cases: + no return Fifo or Abort feature -The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client. + The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client. # Queues of jobs -Queues are type of: notifiedFIFO_t that must be initialized by init_notifiedFIFO() -No delete function is required, the creator has only to free the data of type notifiedFIFO_t + Queues are type of: + notifiedFIFO_t that must be initialized by init_notifiedFIFO() + No delete function is required, the creator has only to free the data of type notifiedFIFO_t -push_notifiedFIFO() add a job in the queue -pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking + push_notifiedFIFO() add a job in the queue + pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking -abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition) + abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition) # Thread pools ## initialization -The clients can create one or more thread pools with init_tpool() -the params string structure: describes a list of cores, separated by "," that run a worker thread + The clients can create one or more thread pools with init_tpool() + the params string structure: + describes a list of cores, separated by "," that run a worker thread -If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and the related code (use negative values is allowed, so the thread will never be mapped on a specific core). + If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and + the related code (use negative values is allowed, so the thread will never be mapped on a specific core). -The threads are all Linux real time scheduler, their name is set automatically is "Tpool_ " + The threads are all Linux real time scheduler, their name is set automatically is "Tpool_ " ## adding jobs -The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO()) + The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO()) -If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job. + If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job. ## abort -A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues. + A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues. -Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue. + Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue. ## Performance measurements -A performance measurement is integrated: the pool will automacillay fill timestamps: + A performance measurement is integrated: + the pool will automacillay fill timestamps: -* creationTime: time the request is push to the pool; -* startProcessingTime: time a worker start to run on the job -* endProcessingTime: time the worker finished the job -* returnTime: time the client reads the result + * creationTime: + time the request is push to the pool; -if you set the environement variable: thread-pool-measurements to a valid file name +* startProcessingTime: +time a worker start to run on the job +* endProcessingTime: +time the worker finished the job +* returnTime: +time the client reads the result + +if you set the environement variable: +thread-pool-measurements to a valid file name These measurements will be wrote to this Linux pipe. -A tool to read the linux fifo and display it in ascii is provided: see the local directory Makefile for this tool and to compile the thread pool unitary tests. +A tool to read the linux fifo and display it in ascii is provided: +see the local directory Makefile for this tool and to compile the thread pool unitary tests. diff --git a/doc/BUILD.md b/doc/BUILD.md index 65567cefa4..388f9f2658 100644 --- a/doc/BUILD.md +++ b/doc/BUILD.md @@ -54,7 +54,7 @@ cd cmake_targets/ ``` - The `-I` option is to install pre-requisites, you only need it the first time you build the softmodem or when some oai dependencies have changed. -- The `-w` option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process. +- The `-w` option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process. The RF simulator[RF simulator](../targets/ARCH/rfsimulator/README.md) is implemented as a specific device replacing RF hardware, it can be build using `-w SIMU` option. - `--eNB` is to build the `lte-softmodem` executable and all required shared libraries - `--UE` is to build the `lte-uesoftmodem` executable and all required shared libraries diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 6ece377293..732534ad68 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -99,17 +99,17 @@ #if defined(ENABLE_ITTI) - extern volatile int start_gNB; - extern volatile int start_UE; + extern volatile int start_gNB; + extern volatile int start_UE; #endif -extern volatile int oai_exit; +extern volatile int oai_exit; extern openair0_config_t openair0_cfg[MAX_CARDS]; extern int transmission_mode; -uint16_t sl_ahead=4; -uint16_t sf_ahead=4; +uint16_t sl_ahead=6; +uint16_t sf_ahead=6; //pthread_t main_gNB_thread; time_stats_t softmodem_stats_mt; // main thread @@ -133,13 +133,14 @@ extern double cpuf; void init_gNB(int,int); void stop_gNB(int nb_inst); -int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx); -int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx); -extern PARALLEL_CONF_t get_thread_parallel_conf(void); -extern WORKER_CONF_t get_thread_worker_conf(void); +int wakeup_txfh(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int frame_tx, int slot_tx, uint64_t timestamp_tx); +int wakeup_tx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, uint64_t timestamp_tx); +#include "executables/thread-common.h" +//extern PARALLEL_CONF_t get_thread_parallel_conf(void); +//extern WORKER_CONF_t get_thread_worker_conf(void); -void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe); +void wakeup_prach_gNB(PHY_VARS_gNB *gNB, RU_t *ru, int frame, int subframe); extern uint8_t nfapi_mode; extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); @@ -149,7 +150,7 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); #define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials) -static inline int rxtx(PHY_VARS_gNB *gNB,int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) { +static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) { start_meas(&softmodem_stats_rxtx_sf); // ******************************************************************* @@ -184,17 +185,15 @@ static inline int rxtx(PHY_VARS_gNB *gNB,int frame_rx, int slot_rx, int frame_tx // **************************************** // Common RX procedures subframe n T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx)); - /* - // if this is IF5 or 3GPP_gNB - if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) { - wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx); - } +/* + // if this is IF5 or 3GPP_gNB + if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) { + wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx); + } + + // UE-specific RX processing for subframe n + if (nfapi_mode == 0 || nfapi_mode == 1) */ - // UE-specific RX processing for subframe n - if (nfapi_mode == 0 || nfapi_mode == 1) { - phy_procedures_gNB_uespec_RX(gNB, proc, no_relay ); - } - */ pthread_mutex_lock(&gNB->UL_INFO_mutex); gNB->UL_INFO.frame = frame_rx; gNB->UL_INFO.slot = slot_rx; @@ -213,6 +212,9 @@ static inline int rxtx(PHY_VARS_gNB *gNB,int frame_rx, int slot_rx, int frame_tx if (oai_exit) return(-1); + //if (slot_rx == NR_UPLINK_SLOT || gNB->frame_parms.frame_type == FDD) + phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); + if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) { phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); } @@ -288,6 +290,8 @@ static void *gNB_L1_thread_tx(void *param) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,slot_tx); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,frame_tx); phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 1 ); pthread_mutex_lock( &L1_proc_tx->mutex ); L1_proc_tx->instance_cnt = -1; @@ -299,6 +303,7 @@ static void *gNB_L1_thread_tx(void *param) { pthread_mutex_unlock(&L1_proc_tx->mutex); wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 ); } @@ -418,10 +423,10 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1); - waitret=timedwait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh",1000000); + waitret=wait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh"); + AssertFatal(release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")==0, "error releaseing gNB lock on RUs\n"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0); - AssertFatal(release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")==0, "error releaseing gNB lock on RUs\n"); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); if (waitret == ETIMEDOUT) { @@ -446,7 +451,7 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot ru = gNB->RU_list[i]; ru_proc = &ru->proc; - AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret); + //AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret); if (ru_proc->instance_cnt_gNBs == 0) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 1); @@ -454,7 +459,7 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); gNB->proc.RU_mask_tx = 0; AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); - AssertFatal((ret=pthread_mutex_unlock( &ru_proc->mutex_gNBs ))==0,"mutex_unlock return %d\n",ret); + //AssertFatal((ret=pthread_mutex_unlock( &ru_proc->mutex_gNBs ))==0,"mutex_unlock return %d\n",ret); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 0); return(-1); @@ -520,6 +525,8 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { RU_proc_t *ru_proc=&ru->proc; int ret; int i; + struct timespec abstime; + int time_ns = 50000; AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret); for (i=0;i num_RU;i++) { @@ -540,14 +547,22 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"muex_unlock returns %d\n",ret); } + clock_gettime(CLOCK_REALTIME, &abstime); + abstime.tv_nsec = abstime.tv_nsec + time_ns; + + if (abstime.tv_nsec >= 1000*1000*1000) { + abstime.tv_nsec -= 1000*1000*1000; + abstime.tv_sec += 1; + } // wake up TX for subframe n+sl_ahead // lock the TX mutex and make sure the thread is ready - AssertFatal((ret=pthread_mutex_lock(&L1_proc->mutex)) == 0,"mutex_lock returns %d\n", ret); + AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret); if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret); LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx); + return(-1); } ++L1_proc->instance_cnt; @@ -929,13 +944,13 @@ void init_gNB(int single_thread_flag,int wait_for_sync) { #ifndef OCP_FRAMEWORK LOG_I(PHY,"Initializing gNB %d\n",inst); #endif + LOG_I(PHY,"Registering with MAC interface module (before %p)\n",gNB->if_inst); AssertFatal((gNB->if_inst = NR_IF_Module_init(inst))!=NULL,"Cannot register interface"); LOG_I(PHY,"Registering with MAC interface module (after %p)\n",gNB->if_inst); gNB->if_inst->NR_Schedule_response = nr_schedule_response; gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO)); - memset((void *)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO)); LOG_I(PHY,"Setting indication lists\n"); gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = gNB->rx_pdu_list; gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = gNB->crc_pdu_list; diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 5bf7ef24ce..44a740a0db 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -81,6 +81,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "enb_config.h" +#include #ifdef SMBV #include "PHY/TOOLS/smbv.h" @@ -90,7 +91,8 @@ unsigned short config_frames[4] = {2,9,11,13}; /* these variables have to be defined before including ENB_APP/enb_paramdef.h and GNB_APP/gnb_paramdef.h */ static int DEFBANDS[] = {7}; static int DEFENBS[] = {0}; - +static int DEFBFW[] = {0x00007fff}; + //static int DEFNRBANDS[] = {7}; //static int DEFGNBS[] = {0}; @@ -114,27 +116,22 @@ static int DEFENBS[] = {0}; #include "T.h" #include "nfapi_interface.h" -extern volatile int oai_exit; +extern volatile int oai_exit; extern void nr_phy_free_RU(RU_t *); extern void nr_phy_config_request(NR_PHY_Config_t *gNB); - -extern PARALLEL_CONF_t get_thread_parallel_conf(void); -extern WORKER_CONF_t get_thread_worker_conf(void); +#include "executables/thread-common.h" +//extern PARALLEL_CONF_t get_thread_parallel_conf(void); +//extern WORKER_CONF_t get_thread_worker_conf(void); void init_NR_RU(char *); void stop_RU(int nb_ru); void do_ru_sync(RU_t *ru); -void configure_ru(int idx, - void *arg); - -void configure_rru(int idx, - void *arg); - +void configure_ru(int idx, void *arg); +void configure_rru(int idx, void *arg); int attach_rru(RU_t *ru); - int connect_rau(RU_t *ru); extern uint16_t sl_ahead; @@ -303,7 +300,7 @@ int connect_rau(RU_t *ru) /* Southbound Fronthaul functions, RCC/RAU */ // southbound IF5 fronthaul for 16-bit OAI format -static inline void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) +void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) { if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); @@ -311,14 +308,15 @@ static inline void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t time } // southbound IF4p5 fronthaul -static inline void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) +void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) { + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx); - if ((nr_slot_select(ru->nr_frame_parms,ru->proc.frame_tx,ru->proc.tti_tx)&NR_DOWNLINK_SLOT) > 0) + if ((nr_slot_select(cfg,ru->proc.frame_tx,ru->proc.tti_tx)&NR_DOWNLINK_SLOT) > 0) send_IF4p5(ru,frame, slot, IF4p5_PDLFFT); } @@ -521,7 +519,7 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *slot) { void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; RU_proc_t *proc = &ru->proc; uint16_t packet_type; uint32_t symbol_number,symbol_mask,symbol_mask_full=0; @@ -534,10 +532,10 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { do { recv_IF4p5(ru, &frame_tx, &slot_tx, &packet_type, &symbol_number); - if (((nr_slot_select(ru->nr_frame_parms,frame_tx,slot_tx) & NR_DOWNLINK_SLOT) > 0) && (symbol_number == 0)) start_meas(&ru->rx_fhaul); + if (((nr_slot_select(cfg,frame_tx,slot_tx) & NR_DOWNLINK_SLOT) > 0) && (symbol_number == 0)) start_meas(&ru->rx_fhaul); - LOG_D(PHY,"subframe %d (%d): frame %d, subframe %d, symbol %d\n", - *slot,nr_slot_select(ru->nr_frame_parms,frame_tx,*slot),frame_tx,slot_tx,symbol_number); + LOG_D(PHY,"slot %d (%d): frame %d, slot %d, symbol %d\n", + *slot,nr_slot_select(cfg,frame_tx,*slot),frame_tx,slot_tx,symbol_number); if (proc->first_tx != 0) { *frame = frame_tx; @@ -556,7 +554,7 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { } else AssertFatal(1==0,"Illegal IF4p5 packet type (should only be IF4p5_PDLFFT%d\n",packet_type); } while (symbol_mask != symbol_mask_full); - if ((nr_slot_select(ru->nr_frame_parms,frame_tx,slot_tx) & NR_DOWNLINK_SLOT)>0) stop_meas(&ru->rx_fhaul); + if ((nr_slot_select(cfg,frame_tx,slot_tx) & NR_DOWNLINK_SLOT)>0) stop_meas(&ru->rx_fhaul); proc->tti_tx = slot_tx; proc->frame_tx = frame_tx; @@ -605,7 +603,7 @@ void fh_if4p5_north_out(RU_t *ru) { stop_meas(&ru->tx_fhaul); } -static void *emulatedRF_thread(void *param) { +void *emulatedRF_thread(void *param) { RU_proc_t *proc = (RU_proc_t *) param; int microsec = 500; // length of time to sleep, in miliseconds struct timespec req = {0}; @@ -653,6 +651,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { ru->nb_rx); } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); proc->timestamp_rx = ts-ru->ts_offset; @@ -674,9 +673,6 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_slot*fp->slots_per_frame))&1023; proc->tti_rx = (proc->timestamp_rx / fp->samples_per_slot)%fp->slots_per_frame; // synchronize first reception to frame 0 subframe 0 - proc->timestamp_tx = proc->timestamp_rx+(sl_ahead*fp->samples_per_slot); - proc->tti_tx = (proc->tti_rx+sl_ahead)%fp->slots_per_frame; - proc->frame_tx = (proc->tti_rx>(fp->slots_per_frame-1-sl_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx; LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n", ru->idx, 0, @@ -718,71 +714,74 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { RU_proc_t *proc = &ru->proc; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; void *txp[ru->nb_tx]; unsigned int txs; - int i; + int i,txsymb; T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot), T_INT(0), T_BUFFER(&ru->common.txdata[0][slot * fp->samples_per_slot], fp->samples_per_slot * 4)); - int slot_type = nr_slot_select(ru->nr_frame_parms,frame,slot%fp->slots_per_frame); - int sf_extension = 0; - if ((slot_type & NR_UPLINK_SLOT) == 0) { + int slot_type = nr_slot_select(cfg,frame,slot%((1< ssb_config.scs_common.value)*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)); + int prevslot_type = nr_slot_select(cfg,frame,(slot+(((1< ssb_config.scs_common.value)*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)-1))%((1< ssb_config.scs_common.value)*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)); + int sf_extension = 0; //sf_extension = ru->sf_extension; + int siglen=fp->samples_per_slot; + int flags=1; - int siglen=fp->samples_per_slot,flags=1; - /* - if (SF_type == SF_S) { - siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0); - flags=3; // end of burst - } - if ((fp->frame_type == TDD) && - (SF_type == SF_DL)&& - (prevSF_type == SF_UL) && - (nextSF_type == SF_DL)) { - flags = 2; // start of burst - sf_extension = ru->N_TA_offset<<1; - } + //nr_subframe_t SF_type = nr_slot_select(cfg,slot%fp->slots_per_frame); + if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT || IS_SOFTMODEM_RFSIM) { - if ((cfg->subframe_config.duplex_mode == TDD) && - (SF_type == SF_DL)&& - (prevSF_type == SF_UL) && - (nextSF_type == SF_UL)) { - flags = 4; // start of burst and end of burst (only one DL SF between two UL) - sf_extension = ru->N_TA_offset<<1; - } */ + if(slot_type == NR_MIXED_SLOT) { + txsymb = 0; + for(int symbol_count =0;symbol_count tdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0) + txsymb++; + } + AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb); + siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + //+ ru->end_of_burst_delay; + flags=3; // end of burst + } + + if (cfg->cell_config.frame_duplex_type.value == TDD && + slot_type == NR_DOWNLINK_SLOT && + prevslot_type == NR_UPLINK_SLOT) { + flags = 2; // start of burst + } + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot ); - for (i=0; i nb_tx; i++) txp[i] = (void *)&ru->common.txdata[i][(slot*fp->samples_per_slot)-sf_extension]; - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - // prepare tx buffer pointers - txs = ru->rfdevice.trx_write_func(&ru->rfdevice, - timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, - txp, - siglen+sf_extension, - ru->nb_tx, - flags); - LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx, - (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen); + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); + // prepare tx buffer pointers + txs = ru->rfdevice.trx_write_func(&ru->rfdevice, + timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, + txp, + siglen+sf_extension, + ru->nb_tx, + flags); + LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, slot %d\n",ru->idx, + (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); + AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %u/%d)\n", txs, siglen); } } + /*! * \brief The Asynchronous RX/TX FH thread of RAU/RCC/gNB/RRU. * This handles the RX FH for an asynchronous RRU/UE * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void *ru_thread_asynch_rxtx( void *param ) { +void *ru_thread_asynch_rxtx( void *param ) { static int ru_thread_asynch_rxtx_status; RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; int slot=0, frame=0; // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe wait_sync("ru_thread_asynch_rxtx"); @@ -806,7 +805,7 @@ static void *ru_thread_asynch_rxtx( void *param ) { // asynchronous receive from north (RRU IF4/IF5) if (ru->fh_north_asynch_in) { - if ((nr_slot_select(ru->nr_frame_parms,frame,slot) & NR_DOWNLINK_SLOT)>0) + if ((nr_slot_select(cfg,frame,slot) & NR_DOWNLINK_SLOT)>0) ru->fh_north_asynch_in(ru,&frame,&slot); } else AssertFatal(1==0,"Unknown function in ru_thread_asynch_rxtx\n"); } @@ -823,7 +822,7 @@ static void *ru_thread_asynch_rxtx( void *param ) { * \param param is a \ref RU_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void *ru_thread_prach( void *param ) { +void *ru_thread_prach( void *param ) { static int ru_thread_prach_status; RU_t *ru = (RU_t *)param; RU_proc_t *proc = (RU_proc_t *)&ru->proc; @@ -859,7 +858,7 @@ static void *ru_thread_prach( void *param ) { 0,0 ); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 ); */ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );*/ if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; } @@ -993,7 +992,7 @@ void wakeup_gNB_L1s(RU_t *ru) { } } -static inline int wakeup_prach_ru(RU_t *ru) { +int wakeup_prach_ru(RU_t *ru) { struct timespec wait; wait.tv_sec=0; wait.tv_nsec=5000000L; @@ -1028,10 +1027,10 @@ static inline int wakeup_prach_ru(RU_t *ru) { void fill_rf_config(RU_t *ru, char *rf_config_file) { int i; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - nfapi_nr_config_request_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index + nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index openair0_config_t *cfg = &ru->openair0_cfg; - int N_RB = gNB_config->rf_config.dl_carrier_bandwidth.value; - int mu = gNB_config->subframe_config.numerology_index_mu.value; + int mu = gNB_config->ssb_config.scs_common.value; + int N_RB = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value; if (mu == NR_MU_0) { //or if LTE if(N_RB == 100) { @@ -1104,7 +1103,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu); } - if (gNB_config->subframe_config.duplex_mode.value==TDD) + if (gNB_config->cell_config.frame_duplex_type.value==TDD) cfg->duplex_mode = duplex_mode_TDD; else //FDD cfg->duplex_mode = duplex_mode_FDD; @@ -1188,7 +1187,7 @@ int setup_RU_buffers(RU_t *ru) { return(0); } -static void *ru_stats_thread(void *param) { +void *ru_stats_thread(void *param) { RU_t *ru = (RU_t *)param; wait_sync("ru_stats_thread"); @@ -1196,14 +1195,20 @@ static void *ru_stats_thread(void *param) { sleep(1); if (opp_enabled == 1) { + if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL); - if (ru->feptx_ofdm) print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL); + if (ru->feptx_ofdm){ + print_meas(&ru->precoding_stats,"feptx_prec",NULL,NULL); + print_meas(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL); + print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL); + print_meas(&ru->ofdm_total_stats,"feptx_total",NULL,NULL); + } if (ru->fh_north_asynch_in) print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL); - if (ru->fh_north_out) { print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL); + if (ru->fh_north_out) { print_meas(&ru->compression,"compression",NULL,NULL); print_meas(&ru->transport,"transport",NULL,NULL); } @@ -1213,13 +1218,13 @@ static void *ru_stats_thread(void *param) { return(NULL); } -static void *ru_thread_tx( void *param ) { - RU_t *ru = (RU_t *)param; - RU_proc_t *proc = &ru->proc; - PHY_VARS_gNB *gNB; - gNB_L1_proc_t *gNB_proc; +void *ru_thread_tx( void *param ) { + RU_t *ru = (RU_t *)param; + RU_proc_t *proc = &ru->proc; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + PHY_VARS_gNB *gNB; + gNB_L1_proc_t *gNB_proc; gNB_L1_rxtx_proc_t *L1_proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; char filename[40]; int print_frame = 8; int i = 0; @@ -1243,12 +1248,14 @@ static void *ru_thread_tx( void *param ) { // wait until eNBs are finished subframe RX n and TX n+4 wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); - AssertFatal((ret=pthread_mutex_lock(&proc->mutex_gNBs))==0,"mutex_lock return %d\n",ret); + ret = pthread_mutex_lock(&proc->mutex_gNBs); + AssertFatal(ret == 0,"mutex_lock return %d\n",ret); int frame_tx=proc->frame_tx; int tti_tx =proc->tti_tx; uint64_t timestamp_tx = proc->timestamp_tx; - AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_gNBs))==0,"mutex_lock returns %d\n",ret); + ret = pthread_mutex_unlock(&proc->mutex_gNBs); + AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); if (oai_exit) break; @@ -1258,7 +1265,7 @@ static void *ru_thread_tx( void *param ) { // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx); - // do OFDM if needed + // do OFDM with/without TX front-end processing if needed if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,tti_tx); if(!emulate_rf) { @@ -1269,8 +1276,17 @@ static void *ru_thread_tx( void *param ) { } else { if(proc->frame_tx == print_frame) { for (i=0; i nb_tx; i++) { - sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); - LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); + + if(proc->tti_tx == 0) { + sprintf(filename,"gNBdataF_frame%d_sl%d.m", print_frame, proc->tti_tx); + LOG_M(filename,"txdataF_frame",&ru->gNB_list[0]->common_vars.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1); + + sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); + LOG_M(filename,"txdataF_frame",&ru->common.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1); + + sprintf(filename,"tx%ddataF_BF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); + LOG_M(filename,"txdataF_BF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); + } if(proc->tti_tx == 9) { sprintf(filename,"tx%ddata_frame%d.m", i, print_frame); @@ -1299,7 +1315,8 @@ static void *ru_thread_tx( void *param ) { gNB = ru->gNB_list[i]; gNB_proc = &gNB->proc; L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &gNB_proc->L1_proc_tx : &gNB_proc->L1_proc; - AssertFatal((ret=pthread_mutex_lock(&gNB_proc->mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); + ret = pthread_mutex_lock(&gNB_proc->mutex_RU_tx); + AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); for (int j=0; j num_RU; j++) { if (ru == gNB->RU_list[j]) { @@ -1312,21 +1329,24 @@ static void *ru_thread_tx( void *param ) { } if (gNB_proc->RU_mask_tx != (1< num_RU)-1) { // not all RUs have provided their information so return - AssertFatal((ret=pthread_mutex_unlock(&gNB_proc->mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); + ret = pthread_mutex_unlock(&gNB_proc->mutex_RU_tx); + AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); } else { // all RUs TX are finished so send the ready signal to gNB processing gNB_proc->RU_mask_tx = 0; - AssertFatal((ret=pthread_mutex_unlock(&gNB_proc->mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); + ret = pthread_mutex_unlock(&gNB_proc->mutex_RU_tx); + AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); - AssertFatal((ret=pthread_mutex_lock(&L1_proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret); + ret = pthread_mutex_lock(&L1_proc->mutex_RUs_tx); + AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); // the thread can now be woken up - if (L1_proc->instance_cnt_RUs==-1) { - AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0, + //if (L1_proc->instance_cnt_RUs == -1) { + L1_proc->instance_cnt_RUs = 0; + AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0, "ERROR pthread_cond_signal for gNB_L1_thread\n"); - } //else AssertFatal(1==0,"gNB TX thread is not ready\n"); - L1_proc->instance_cnt_RUs = 0; + //} //else AssertFatal(1==0,"gNB TX thread is not ready\n"); + ret = pthread_mutex_unlock(&L1_proc->mutex_RUs_tx); + AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs); - AssertFatal((ret=pthread_mutex_unlock(&L1_proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret); - } } } @@ -1335,17 +1355,19 @@ static void *ru_thread_tx( void *param ) { return 0; } -static void *ru_thread( void *param ) { +void *ru_thread( void *param ) { static int ru_thread_status; RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; int ret; - int slot = fp->slots_per_frame-1; - int frame =1023; - char filename[40],threadname[40]; + int slot = fp->slots_per_frame-1; + int frame = 1023; + char filename[40], threadname[40]; int print_frame = 8; int i = 0; + int aa; + // set default return value ru_thread_status = 0; // set default return value @@ -1377,9 +1399,9 @@ static void *ru_thread( void *param ) { } if (ru->if_south == LOCAL_RF) { // configure RF parameters only - fill_rf_config(ru,ru->rf_config_file); nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp); nr_dump_frame_parms(fp); + fill_rf_config(ru,ru->rf_config_file); nr_phy_init_RU(ru); ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); AssertFatal(ret==0,"Cannot connect to local radio\n"); @@ -1438,6 +1460,7 @@ static void *ru_thread( void *param ) { } // synchronization on input FH interface, acquire signals/data and block + LOG_D(PHY,"[RU_thread] read data: frame_rx = %d, tti_rx = %d\n", frame, slot); if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot); else AssertFatal(1==0, "No fronthaul interface at south port"); @@ -1462,7 +1485,19 @@ static void *ru_thread( void *param ) { if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; // do RX front-end processing (frequency-shift, dft) if needed - if (ru->feprx) ru->feprx(ru,proc->tti_rx); + + if (proc->tti_rx == NR_UPLINK_SLOT || fp->frame_type == FDD) { + + if (ru->feprx) ru->feprx(ru,proc->tti_rx); + + } + + LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx); + LOG_D(PHY,"Copying rxdataF from RU to gNB\n"); + + for (aa=0;aa nb_rx;aa++) + memcpy((void*)RC.gNB[0]->common_vars.rxdataF[aa], + (void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t)); // At this point, all information for subframe has been received on FH interface @@ -1473,7 +1508,7 @@ static void *ru_thread( void *param ) { // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx); - // do OFDM if needed + // do OFDM with/without TX front-end processing if needed if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx); if(!emulate_rf) { @@ -1612,13 +1647,6 @@ int stop_rf(RU_t *ru) { return 0; } -extern void fep_full(RU_t *ru,int slot); -extern void ru_fep_full_2thread(RU_t *ru,int slot); -extern void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); -extern void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx); -extern void feptx_prec(RU_t *ru, int frame_tx,int tti_tx); -extern void init_fep_thread(RU_t *ru); -extern void nr_init_feptx_thread(RU_t *ru); void init_RU_proc(RU_t *ru) { int i=0; @@ -1631,7 +1659,7 @@ void init_RU_proc(RU_t *ru) { memset((void *)proc,0,sizeof(RU_proc_t)); proc->ru = ru; proc->instance_cnt_prach = -1; - proc->instance_cnt_synch = -1; ; + proc->instance_cnt_synch = -1; proc->instance_cnt_FH = -1; proc->instance_cnt_FH1 = -1; proc->instance_cnt_gNBs = -1; @@ -1642,6 +1670,7 @@ void init_RU_proc(RU_t *ru) { proc->frame_offset = 0; proc->num_slaves = 0; proc->frame_tx_unwrap = 0; + proc->feptx_mask = 0; for (i=0; i<10; i++) proc->symbol_mask[i]=0; @@ -1684,7 +1713,7 @@ void init_RU_proc(RU_t *ru) { } if (get_thread_worker_conf() == WORKER_ENABLE) { - if (ru->feprx) init_fep_thread(ru); + if (ru->feprx) nr_init_feprx_thread(ru); if (ru->feptx_ofdm) nr_init_feptx_thread(ru); } @@ -1838,14 +1867,14 @@ void configure_ru(int idx, RU_t *ru = RC.ru[idx]; RRU_config_t *config = (RRU_config_t *)arg; RRU_capabilities_t *capabilities = (RRU_capabilities_t *)arg; - nfapi_nr_config_request_t *gNB_config = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; int ret; LOG_I(PHY, "Received capabilities from RRU %d\n",idx); if (capabilities->FH_fmt < MAX_FH_FMTs) LOG_I(PHY, "RU FH options %s\n",rru_format_options[capabilities->FH_fmt]); - AssertFatal((ret=check_capabilities(ru,capabilities)) == 0, - "Cannot configure RRU %d, check_capabilities returned %d\n", idx,ret); + ret = check_capabilities(ru,capabilities); + AssertFatal(ret == 0, "Cannot configure RRU %d, check_capabilities returned %d\n", idx, ret); // take antenna capabilities of RRU ru->nb_tx = capabilities->nb_tx[0]; ru->nb_rx = capabilities->nb_rx[0]; @@ -1861,8 +1890,8 @@ void configure_ru(int idx, //config->tdd_config_S[0] = ru->nr_frame_parms->tdd_config_S; config->att_tx[0] = ru->att_tx; config->att_rx[0] = ru->att_rx; - config->N_RB_DL[0] = gNB_config->rf_config.dl_carrier_bandwidth.value; - config->N_RB_UL[0] = gNB_config->rf_config.ul_carrier_bandwidth.value; + config->N_RB_DL[0] = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value; + config->N_RB_UL[0] = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value; config->threequarter_fs[0] = ru->nr_frame_parms->threequarter_fs; /* if (ru->if_south==REMOTE_IF4p5) { config->prach_FreqOffset[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset; @@ -1877,22 +1906,23 @@ void configure_rru(int idx, void *arg) { RRU_config_t *config = (RRU_config_t *)arg; RU_t *ru = RC.ru[idx]; - nfapi_nr_config_request_t *gNB_config = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; ru->nr_frame_parms->eutra_band = config->band_list[0]; ru->nr_frame_parms->dl_CarrierFreq = config->tx_freq[0]; ru->nr_frame_parms->ul_CarrierFreq = config->rx_freq[0]; if (ru->nr_frame_parms->dl_CarrierFreq == ru->nr_frame_parms->ul_CarrierFreq) { - gNB_config->subframe_config.duplex_mode.value = TDD; + gNB_config->cell_config.frame_duplex_type.value = TDD; //ru->nr_frame_parms->tdd_config = config->tdd_config[0]; //ru->nr_frame_parms->tdd_config_S = config->tdd_config_S[0]; } else - gNB_config->subframe_config.duplex_mode.value = FDD; + gNB_config->cell_config.frame_duplex_type.value = FDD; ru->att_tx = config->att_tx[0]; ru->att_rx = config->att_rx[0]; - gNB_config->rf_config.dl_carrier_bandwidth.value = config->N_RB_DL[0]; - gNB_config->rf_config.ul_carrier_bandwidth.value = config->N_RB_UL[0]; + int mu = gNB_config->ssb_config.scs_common.value; + gNB_config->carrier_config.dl_grid_size[mu].value = config->N_RB_DL[0]; + gNB_config->carrier_config.dl_grid_size[mu].value = config->N_RB_UL[0]; ru->nr_frame_parms->threequarter_fs = config->threequarter_fs[0]; //ru->nr_frame_parms->pdsch_config_common.referenceSignalPower = ru->max_pdschReferenceSignalPower-config->att_tx[0]; @@ -1977,8 +2007,8 @@ void set_function_spec_param(RU_t *ru) { ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception ru->fh_south_out = tx_rf; // send output to RF ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously - ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? ru_fep_full_2thread : fep_full; // RX DFTs - ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft only (no precoding in RRU) + ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // RX DFTs + ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft only (no precoding in RRU) ru->feptx_prec = NULL; ru->nr_start_if = nr_start_if; // need to start the if interface for if4p5 ru->ifdevice.host_type = RRU_HOST; @@ -1999,9 +2029,9 @@ void set_function_spec_param(RU_t *ru) { malloc_IF4p5_buffer(ru); } else if (ru->function == gNodeB_3GPP) { ru->do_prach = 0; // no prach processing in RU - ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? ru_fep_full_2thread : fep_full; // RX DFTs + ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // RX DFTs ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft and precoding - ru->feptx_prec = NULL; // this is fep with idft and precoding + ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // this is fep with idft and precoding ru->fh_north_in = NULL; // no incoming fronthaul from north ru->fh_north_out = NULL; // no outgoing fronthaul to north ru->nr_start_if = NULL; // no if interface @@ -2029,13 +2059,13 @@ void set_function_spec_param(RU_t *ru) { case REMOTE_IF5: // the remote unit is IF5 RRU ru->do_prach = 0; - ru->feprx = fep_full; // this is frequency-shift + DFTs - ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs - ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // need to do transmit Precoding + IDFTs - ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception - ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission - ru->fh_south_asynch_in = NULL; // no asynchronous UL - ru->start_rf = NULL; // no local RF + ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // this is frequency-shift + DFTs + ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // need to do transmit Precoding + IDFTs + ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // need to do transmit Precoding + IDFTs + ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception + ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission + ru->fh_south_asynch_in = NULL; // no asynchronous UL + ru->start_rf = NULL; // no local RF ru->stop_rf = NULL; ru->nr_start_if = nr_start_if; // need to start if interface for IF5 ru->ifdevice.host_type = RAU_HOST; @@ -2054,7 +2084,7 @@ void set_function_spec_param(RU_t *ru) { case REMOTE_IF4p5: ru->do_prach = 0; ru->feprx = NULL; // DFTs - ru->feptx_prec = feptx_prec; // Precoding operation + ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // Precoding operation ru->feptx_ofdm = NULL; // no OFDM mod ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission @@ -2084,12 +2114,11 @@ void set_function_spec_param(RU_t *ru) { } // switch on interface type } -extern void RCconfig_RU(void); - void init_NR_RU(char *rf_config_file) { int ru_id; RU_t *ru; + PHY_VARS_gNB *gNB_RC; PHY_VARS_gNB *gNB0= (PHY_VARS_gNB *)NULL; NR_DL_FRAME_PARMS *fp = (NR_DL_FRAME_PARMS *)NULL; int i; @@ -2129,6 +2158,7 @@ void init_NR_RU(char *rf_config_file) } } + gNB_RC = RC.gNB[0]; gNB0 = ru->gNB_list[0]; fp = ru->nr_frame_parms; LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south); @@ -2137,10 +2167,11 @@ void init_NR_RU(char *rf_config_file) if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5)) AssertFatal(gNB0!=NULL,"gNB0 is null!\n"); - if (gNB0) { - LOG_I(PHY,"Copying frame parms from gNB %d to ru %d\n",gNB0->Mod_id,ru->idx); - memcpy((void *)fp,(void *)&gNB0->frame_parms,sizeof(NR_DL_FRAME_PARMS)); - memset((void *)ru->frame_parms, 0, sizeof(LTE_DL_FRAME_PARMS)); + if (gNB0 && gNB_RC) { + LOG_I(PHY,"Copying frame parms from gNB in RC to gNB %d in ru %d and frame_parms in ru\n",gNB0->Mod_id,ru->idx); + memset((void *)fp, 0, sizeof(NR_DL_FRAME_PARMS)); + memcpy((void *)fp,&gNB_RC->frame_parms,sizeof(NR_DL_FRAME_PARMS)); + memcpy((void *)&gNB0->frame_parms,(void *)&gNB_RC->frame_parms,sizeof(NR_DL_FRAME_PARMS)); // attach all RU to all gNBs in its list/ LOG_D(PHY,"ru->num_gNB:%d gNB0->num_RU:%d\n", ru->num_gNB, gNB0->num_RU); @@ -2219,6 +2250,9 @@ void RCconfig_RU(void) LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr)); } } + else { + RC.ru[j]->openair0_cfg.clock_source = unset; + } if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) { if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) { @@ -2296,6 +2330,14 @@ void RCconfig_RU(void) RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr); RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); + + if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) { + RC.ru[j]->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt; + for (i=0; i num_gNB; i++) { + RC.ru[j]->bw_list[i] = (int32_t *)malloc16_clear((RC.ru[j]->nb_bfw)*sizeof(int32_t)); + for (int b=0; b nb_bfw; b++) RC.ru[j]->bw_list[i][b] = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].iptr[b]; + } + } }// j=0..num_rus } else { RC.nb_RU = 0; @@ -2303,3 +2345,4 @@ void RCconfig_RU(void) return; } + diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index 0fec975e6f..c9d0930e83 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -1,7 +1,7 @@ #ifndef NR_SOFTMODEM_COMMON_H #define NR_SOFTMODEM_COMMON_H -#ifndef _GNU_SOURCE +#ifndef _GNU_SOURCE #define _GNU_SOURCE #endif @@ -83,6 +83,7 @@ #define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" #define CONFIG_HLP_DISABLETIMECORR "disable UE timing correction\n" +#define CONFIG_HLP_RRC_CFG_PATH "path for RRC configuration\n" #define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n" #define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n" @@ -98,6 +99,8 @@ #define CONFIG_HLP_TELN "Start embedded telnet server \n" #define CONFIG_HLP_MSC "Enable the MSC tracing utility \n" #define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n" +#define CONFIG_HLP_NOS1 "Disable s1 interface\n" +#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n" /*--------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters for LOG utility */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 00865f8799..61d6362e9e 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -83,6 +83,8 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "PHY/TOOLS/nr_phy_scope.h" #include "stats.h" #include "nr-softmodem.h" +#include "executables/softmodem-common.h" +#include "executables/thread-common.h" #include "NB_IoT_interface.h" #include "x2ap_eNB.h" @@ -105,7 +107,6 @@ int config_sync_var=-1; #endif volatile int oai_exit = 0; -static clock_source_t clock_source = internal; static int wait_for_sync = 0; unsigned int mmapped_dma=0; @@ -168,7 +169,7 @@ int rx_input_level_dBm; uint32_t do_forms=0; int otg_enabled; -//int number_of_cards = 1; +//int number_of_cards = 1; //static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; @@ -189,46 +190,10 @@ int transmission_mode=1; int emulate_rf = 0; int numerology = 0; -typedef struct { - uint64_t optmask; - THREAD_STRUCT thread_struct; - char rf_config_file[1024]; - int phy_test; - uint8_t usim_test; - int emulate_rf; - int wait_for_sync; //eNodeB only - int single_thread_flag; //eNodeB only - int chain_offset; - int numerology; - unsigned int start_msc; - uint32_t clock_source; - int hw_timing_advance; -} softmodem_params_t; static softmodem_params_t softmodem_params; static char *parallel_config = NULL; static char *worker_config = NULL; -static THREAD_STRUCT thread_struct; - -void set_parallel_conf(char *parallel_conf) { - if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; - - printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); -} -void set_worker_conf(char *worker_conf) { - if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; - else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; - - printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); -} -PARALLEL_CONF_t get_thread_parallel_conf(void) { - return thread_struct.parallel_conf; -} -WORKER_CONF_t get_thread_worker_conf(void) { - return thread_struct.worker_conf; -} /* struct for ethernet specific parameters given in eNB conf file */ eth_params_t *eth_params; @@ -246,7 +211,7 @@ char uecap_xer_in=0; uint8_t abstraction_flag=0; /* forward declarations */ -void set_default_frame_parms(nfapi_nr_config_request_t *config[MAX_NUM_CCs], NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); +void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs], NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); /*---------------------BMC: timespec helpers -----------------------------*/ @@ -520,7 +485,9 @@ static void get_options(void) { int tddflag, nonbiotflag; uint32_t online_log_messages; uint32_t glog_level, glog_verbosity; - uint32_t start_telnetsrv; + uint32_t start_telnetsrv = 0; + uint32_t noS1; + uint32_t nokrnmod; paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ; paramdef_t cmdline_logparams[] = CMDLINE_LOGPARAMS_DESC_NR ; config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); @@ -558,6 +525,7 @@ static void get_options(void) { if(parallel_config != NULL) set_parallel_conf(parallel_config); if(worker_config != NULL) set_worker_conf(worker_config); + } @@ -569,18 +537,18 @@ static void get_options(void) { -void set_default_frame_parms(nfapi_nr_config_request_t *config[MAX_NUM_CCs], - NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) +void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs], + NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { for (int CC_id=0; CC_id subframe_config.numerology_index_mu.value =1; - config[CC_id]->subframe_config.duplex_mode.value = 1; //FDD - config[CC_id]->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL - config[CC_id]->rf_config.dl_carrier_bandwidth.value = 106; - config[CC_id]->rf_config.ul_carrier_bandwidth.value = 106; - config[CC_id]->sch_config.physical_cell_id.value = 0; + config[CC_id] = (nfapi_nr_config_request_scf_t *) malloc(sizeof(nfapi_nr_config_request_scf_t)); + config[CC_id]->ssb_config.scs_common.value = 1; + config[CC_id]->cell_config.frame_duplex_type.value = 1; //FDD + //config[CC_id]->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL + config[CC_id]->carrier_config.dl_grid_size[1].value = 106; + config[CC_id]->carrier_config.ul_grid_size[1].value = 106; + config[CC_id]->cell_config.phy_cell_id.value = 0; ///dl frequency to be filled in /* //Set some default values that may be overwritten while reading options frame_parms[CC_id]->frame_type = FDD; @@ -873,6 +841,30 @@ static void wait_nfapi_init(char *thread_name) { printf( "NFAPI: got sync (%s)\n", thread_name); } +void init_pdcp(void) { + //if (!NODE_IS_DU(RC.rrc[0]->node_type)) { + pdcp_layer_init(); + uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ? + (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT; + + if (IS_SOFTMODEM_NOS1){ + printf("IS_SOFTMODEM_NOS1 option enabled \n"); + pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ; + } + + pdcp_module_init(pdcp_initmask); + + /*if (NODE_IS_CU(RC.rrc[0]->node_type)) { + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req); + } else {*/ + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req); + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); + //} + /*} else { + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind); + }*/ +} + int main( int argc, char **argv ) { int i, ru_id, CC_id = 0; @@ -894,6 +886,7 @@ int main( int argc, char **argv ) configure_linux(); printf("Reading in command-line options\n"); get_options (); + get_common_options(); if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { fprintf(stderr,"Getting configuration failed\n"); @@ -939,6 +932,9 @@ init_opt(); #endif LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); + if(IS_SOFTMODEM_NOS1) + init_pdcp(); + if (RC.nb_nr_inst > 0) { // don't create if node doesn't connect to RRC/S1/GTP @@ -958,6 +954,7 @@ init_opt(); flexran_agent_start(i); } */ + // init UE_PF_PO and mutex lock pthread_mutex_init(&ue_pf_po_mutex, NULL); memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index 50e0c5469f..8334c99134 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -5,25 +5,24 @@ #include "flexran_agent.h" #include "PHY/defs_gNB.h" +#include "proto_agent.h" #define DEFAULT_DLF 2680000000 - /***************************************************************************************************************************************/ /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument when calling config_get or config_getlist functions */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters common to eNodeB and UE */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters common to eNodeB and UE */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CMDLINE_PARAMS_DESC_GNB { \ {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)},\ {"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ - {"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \ {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ @@ -42,14 +41,21 @@ {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ - {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \ + {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0}, \ + {"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \ + {"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0} \ } +#define SOFTMODEM_NOS1_BIT (1<<0) +#define SOFTMODEM_NOKRNMOD_BIT (1<<1) +#define SOFTMODEM_RFSIM_BIT (1<<10) -typedef struct { - int *argc; - char **argv; -} scopeParms_t; +#define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT) +#define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT) + +#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT) +extern uint64_t get_softmodem_optmask(void); +extern void get_common_options(void); extern int T_port; extern int T_nowait; diff --git a/executables/nr-ue.c b/executables/nr-ue.c index f2115fc6ea..79ea205680 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -45,6 +45,7 @@ #include "common/utils/LOG/log.h" #include "common/utils/system.h" #include "common/utils/LOG/vcd_signal_dumper.h" +#include "executables/nr-softmodem.h" #include "T.h" @@ -141,8 +142,10 @@ PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms, ue = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE)); memset(ue,0,sizeof(PHY_VARS_NR_UE)); memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS)); + ue->Mod_id = UE_id; ue->mac_enabled = 1; + // initialize all signal buffers init_nr_ue_signal(ue,1,abstraction_flag); // intialize transport @@ -353,6 +356,9 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { nr_dcireq_t dcireq; nr_scheduled_response_t scheduled_response; + uint32_t nb_rb, start_rb; + uint8_t nb_symb_sch, start_symbol, mcs, precod_nbr_layers, harq_pid, rvidx; + uint16_t n_rnti; // Process Rx data for one sub-frame if (nr_slot_select(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_DOWNLINK_SLOT) { @@ -365,22 +371,57 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { nr_ue_dcireq(&dcireq); //to be replaced with function pointer later scheduled_response.dl_config = &dcireq.dl_config_req; - scheduled_response.ul_config = NULL; + scheduled_response.ul_config = &dcireq.ul_config_req; scheduled_response.tx_request = NULL; scheduled_response.module_id = UE->Mod_id; scheduled_response.CC_id = 0; scheduled_response.frame = proc->frame_rx; scheduled_response.slot = proc->nr_tti_rx; + + //--------------------------Temporary configuration-----------------------------// + n_rnti = 0x1234; + nb_rb = 50; + start_rb = 0; + nb_symb_sch = 12; + start_symbol = 2; + precod_nbr_layers = 1; + mcs = 9; + harq_pid = 0; + rvidx = 0; + //------------------------------------------------------------------------------// + + scheduled_response.ul_config->sfn_slot = NR_UPLINK_SLOT; + scheduled_response.ul_config->number_pdus = 1; + scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.rnti = n_rnti; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_rbs = nb_rb; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_rb = start_rb; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_symbols = nb_symb_sch; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_symbol = start_symbol; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.mcs = mcs; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.ndi = 0; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.rv = rvidx; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.n_layers = precod_nbr_layers; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = harq_pid; nr_ue_scheduled_response(&scheduled_response); #ifdef UE_SLOT_PARALLELISATION phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL ); #else uint64_t a=rdtsc(); - phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode, scheduled_response.dl_config); + phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode); LOG_D(PHY,"phy_procedures_nrUE_RX: slot:%d, time %lu\n", proc->nr_tti_rx, (rdtsc()-a)/3500); //printf(">>> nr_ue_pdcch_procedures ended\n"); #endif + if(IS_SOFTMODEM_NOS1){ //&& proc->nr_tti_rx==1 + //Hardcoded rnti value + protocol_ctxt_t ctxt; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO, + 0x1234, proc->frame_rx, + proc->nr_tti_rx, 0); + pdcp_run(&ctxt); + pdcp_fifo_flush_sdus(&ctxt); + } } @@ -415,13 +456,14 @@ typedef struct processingData_s { } processingData_t; void UE_processing(void *arg) { + uint8_t thread_id; processingData_t *rxtxD=(processingData_t *) arg; UE_nr_rxtx_proc_t *proc = &rxtxD->proc; PHY_VARS_NR_UE *UE = rxtxD->UE; processSlotRX(UE, proc); //printf(">>> mac ended\n"); // Prepare the future Tx data -#if 0 +/* #ifndef NO_RAT_NR if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_UPLINK_SLOT) @@ -429,11 +471,21 @@ void UE_processing(void *arg) { if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || (UE->frame_parms.frame_type == FDD) ) #endif +*/ + + + if (proc->nr_tti_tx == NR_UPLINK_SLOT || UE->frame_parms.frame_type == FDD){ + + thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_tx]; + + if (UE->mode != loop_through_memory) - phy_procedures_nrUE_TX(UE,proc,0,0,UE->mode,no_relay); + phy_procedures_nrUE_TX(UE,proc,0,thread_id); + + } //phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay); -#endif + #if 0 if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) && @@ -486,6 +538,9 @@ void trashFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { dummy_rx, UE->frame_parms.samples_per_subframe, UE->frame_parms.nb_antennas_rx); + if (IS_SOFTMODEM_RFSIM ) { + usleep(1000); // slow down, as would do actuall rf to let cpu for the synchro thread + } } for (int i=0; i frame_parms.nb_antennas_tx; i++) @@ -643,12 +698,12 @@ void *UE_thread(void *arg) { //LOG_I(PHY,"Process slot %d thread Idx %d total gain %d\n", slot_nr, thread_idx, UE->rx_total_gain_dB); #ifdef OAI_ADRV9371_ZC706 - uint32_t total_gain_dB_prev = 0; + /*uint32_t total_gain_dB_prev = 0; if (total_gain_dB_prev != UE->rx_total_gain_dB) { total_gain_dB_prev = UE->rx_total_gain_dB; - openair0_cfg[0].rx_gain[0] = UE->rx_total_gain_dB-20; + openair0_cfg[0].rx_gain[0] = UE->rx_total_gain_dB; UE->rfdevice.trx_set_gains_func(&UE->rfdevice,&openair0_cfg[0]); - } + }*/ #endif for (int i=0; i frame_parms.nb_antennas_rx; i++) @@ -657,7 +712,7 @@ void *UE_thread(void *arg) { slot_nr*UE->frame_parms.samples_per_slot]; for (int i=0; i frame_parms.nb_antennas_tx; i++) - txp[i] = (void *)&UE->common_vars.txdata[i][curMsg->proc.nr_tti_tx*UE->frame_parms.samples_per_slot]; + txp[i] = (void *)&UE->common_vars.txdata[i][((curMsg->proc.nr_tti_rx + DURATION_RX_TO_TX)%nb_slot_frame)*UE->frame_parms.samples_per_slot]; int readBlockSize, writeBlockSize; @@ -680,16 +735,18 @@ void *UE_thread(void *arg) { rxp, readBlockSize, UE->frame_parms.nb_antennas_rx),""); + +if (slot_nr==18) AssertFatal( writeBlockSize == UE->rfdevice.trx_write_func(&UE->rfdevice, timestamp+ - (2*UE->frame_parms.samples_per_slot) - + (DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot) - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - openair0_cfg[0].tx_sample_advance, txp, writeBlockSize, UE->frame_parms.nb_antennas_tx, - 1),""); + 4),""); if( slot_nr==(nb_slot_frame-1)) { // read in first symbol of next frame and adjust for timing drift @@ -734,7 +791,7 @@ void *UE_thread(void *arg) { msgToPush->key=slot_nr; pushTpool(Tpool, msgToPush); - if (getenv("RFSIMULATOR")) { + if (getenv("RFSIMULATOR") || IS_SOFTMODEM_NOS1) { //getenv("RFSIMULATOR") // FixMe: Wait previous thread is done, because race conditions seems too bad // in case of actual RF board, the overlap between threads mitigate the issue // We must receive one message, that proves the slot processing is done @@ -752,7 +809,7 @@ void *UE_thread(void *arg) { return NULL; } -void init_NR_UE(int nb_inst) { +void init_NR_UE(int nb_inst, char* rrc_config_path) { int inst; NR_UE_MAC_INST_t *mac_inst; pthread_t threads[nb_inst]; @@ -760,21 +817,10 @@ void init_NR_UE(int nb_inst) { for (inst=0; inst < nb_inst; inst++) { PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0]; AssertFatal((UE->if_inst = nr_ue_if_module_init(inst)) != NULL, "can not initial IF module\n"); - nr_l3_init_ue(); + nr_l3_init_ue(rrc_config_path); nr_l2_init_ue(); mac_inst = get_mac_inst(inst); mac_inst->if_module = UE->if_inst; - // Initial bandwidth part configuration -- full carrier bandwidth - mac_inst->initial_bwp_dl.bwp_id = 0; - mac_inst->initial_bwp_dl.location = 0; - mac_inst->initial_bwp_dl.scs = UE->frame_parms.subcarrier_spacing; - mac_inst->initial_bwp_dl.N_RB = UE->frame_parms.N_RB_DL; - mac_inst->initial_bwp_dl.cyclic_prefix = UE->frame_parms.Ncp; - mac_inst->initial_bwp_ul.bwp_id = 0; - mac_inst->initial_bwp_ul.location = 0; - mac_inst->initial_bwp_ul.scs = UE->frame_parms.subcarrier_spacing; - mac_inst->initial_bwp_ul.N_RB = UE->frame_parms.N_RB_UL; - mac_inst->initial_bwp_ul.cyclic_prefix = UE->frame_parms.Ncp; LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); threadCreate(&threads[inst], UE_thread, (void *)UE, "UEthread", -1, OAI_PRIORITY_RT_MAX); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 9a4a0cdf70..e535040fa9 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -29,6 +29,7 @@ #include "PHY/defs_nr_UE.h" #include "common/ran_context.h" #include "common/config/config_userapi.h" +//#include "common/utils/threadPool/thread-pool.h" #include "common/utils/load_module_shlib.h" //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all @@ -77,9 +78,11 @@ unsigned short config_frames[4] = {2,9,11,13}; #include + /* Callbacks, globals and object handlers */ extern void reset_stats( FL_OBJECT *, long ); +//extern void initTpool(char *params,tpool_t *pool, bool performanceMeas); /* Forms and Objects */ @@ -102,16 +105,18 @@ FD_phy_scope_nrue *form_nrue[NUMBER_OF_UE_MAX]; //FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; //FD_stats_form *form_stats=NULL,*form_stats_l2=NULL; char title[255]; -static pthread_t forms_thread; //xforms +static pthread_t forms_thread; //xforms #include +#include "executables/softmodem-common.h" +#include "executables/thread-common.h" RAN_CONTEXT_t RC; volatile int start_eNB = 0; volatile int start_UE = 0; volatile int oai_exit = 0; -static clock_source_t clock_source = internal; +static clock_source_t clock_source = unset; int single_thread_flag=1; static double snr_dB=20; @@ -147,7 +152,7 @@ double bw = 10.0e6; static int tx_max_power[MAX_NUM_CCs] = {0}; -char rf_config_file[1024]; +char rf_config_file[1024]; int chain_offset=0; int phy_test = 0; @@ -162,53 +167,18 @@ uint8_t nb_antenna_rx = 1; char ref[128] = "internal"; char channels[128] = "0"; -typedef struct { - uint64_t optmask; - THREAD_STRUCT thread_struct; - char rf_config_file[1024]; - int phy_test; - uint8_t usim_test; - int emulate_rf; - int wait_for_sync; //eNodeB only - int single_thread_flag; //eNodeB only - int chain_offset; - int numerology; - unsigned int start_msc; - uint32_t clock_source; - int hw_timing_advance; -} softmodem_params_t; static softmodem_params_t softmodem_params; static char *parallel_config = NULL; static char *worker_config = NULL; -static THREAD_STRUCT thread_struct; -void set_parallel_conf(char *parallel_conf) { - if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; - - printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); -} -void set_worker_conf(char *worker_conf) { - if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; - else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; - - printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); -} -PARALLEL_CONF_t get_thread_parallel_conf(void) { - return thread_struct.parallel_conf; -} -WORKER_CONF_t get_thread_worker_conf(void) { - return thread_struct.worker_conf; -} int rx_input_level_dBm; //static int online_log_messages=0; uint32_t do_forms=0; int otg_enabled; -//int number_of_cards = 1; +//int number_of_cards = 1; static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; int16_t node_synch_ref[MAX_NUM_CCs]; @@ -239,6 +209,8 @@ tpool_t *Tpool; char *usrp_args=NULL; +char *rrc_config_path=NULL; + /* forward declarations */ void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); @@ -404,6 +376,8 @@ static void get_options(void) { uint32_t online_log_messages; uint32_t glog_level, glog_verbosity; uint32_t start_telnetsrv=0; + //uint32_t noS1; + //uint32_t nokrnmod; paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ; paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC_NR ; config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); @@ -549,14 +523,23 @@ void init_openair0(void) { if (frame_parms[0]->threequarter_fs) { openair0_cfg[card].sample_rate=92.16e6; openair0_cfg[card].samples_per_frame = 921600; - openair0_cfg[card].tx_bw = 40e6; - openair0_cfg[card].rx_bw = 40e6; } else { openair0_cfg[card].sample_rate=122.88e6; openair0_cfg[card].samples_per_frame = 1228800; - openair0_cfg[card].tx_bw = 40e6; - openair0_cfg[card].rx_bw = 40e6; + } + } else { + LOG_E(PHY,"Unsupported numerology!\n"); + exit(-1); + } + }else if(frame_parms[0]->N_RB_DL == 273) { + if (numerology==1) { + if (frame_parms[0]->threequarter_fs) { + AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n"); + } + else { + openair0_cfg[card].sample_rate=122.88e6; + openair0_cfg[card].samples_per_frame = 1228800; } } else { LOG_E(PHY,"Unsupported numerology!\n"); @@ -567,32 +550,22 @@ void init_openair0(void) { if (frame_parms[0]->threequarter_fs) { openair0_cfg[card].sample_rate=23.04e6; openair0_cfg[card].samples_per_frame = 230400; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; } else { openair0_cfg[card].sample_rate=30.72e6; openair0_cfg[card].samples_per_frame = 307200; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; } } else if (numerology==1) { if (frame_parms[0]->threequarter_fs) { openair0_cfg[card].sample_rate=46.08e6; openair0_cfg[card].samples_per_frame = 480800; - openair0_cfg[card].tx_bw = 20e6; - openair0_cfg[card].rx_bw = 20e6; } else { openair0_cfg[card].sample_rate=61.44e6; openair0_cfg[card].samples_per_frame = 614400; - openair0_cfg[card].tx_bw = 20e6; - openair0_cfg[card].rx_bw = 20e6; } } else if (numerology==2) { openair0_cfg[card].sample_rate=122.88e6; openair0_cfg[card].samples_per_frame = 1228800; - openair0_cfg[card].tx_bw = 40e6; - openair0_cfg[card].rx_bw = 40e6; } else { LOG_E(PHY,"Unsupported numerology!\n"); exit(-1); @@ -600,18 +573,12 @@ void init_openair0(void) { } else if(frame_parms[0]->N_RB_DL == 50) { openair0_cfg[card].sample_rate=15.36e6; openair0_cfg[card].samples_per_frame = 153600; - openair0_cfg[card].tx_bw = 5e6; - openair0_cfg[card].rx_bw = 5e6; } else if (frame_parms[0]->N_RB_DL == 25) { openair0_cfg[card].sample_rate=7.68e6; openair0_cfg[card].samples_per_frame = 76800; - openair0_cfg[card].tx_bw = 2.5e6; - openair0_cfg[card].rx_bw = 2.5e6; } else if (frame_parms[0]->N_RB_DL == 6) { openair0_cfg[card].sample_rate=1.92e6; openair0_cfg[card].samples_per_frame = 19200; - openair0_cfg[card].tx_bw = 1.5e6; - openair0_cfg[card].rx_bw = 1.5e6; } else { LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms[0]->N_RB_DL); @@ -659,6 +626,27 @@ void init_openair0(void) { } } +void init_pdcp(void) { + uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1) ? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT); + + /*if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM || (nfapi_getmode()==NFAPI_UE_STUB_PNF)) { + pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; + }*/ + + if (IS_SOFTMODEM_NOKRNMOD) + pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; + + /*if (rlc_module_init() != 0) { + LOG_I(RLC, "Problem at RLC initiation \n"); + } + pdcp_layer_init(); + nr_ip_over_LTE_DRB_preconfiguration();*/ + pdcp_module_init(pdcp_initmask); + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req); + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); + LOG_I(PDCP, "Before getting out from init_pdcp() \n"); +} + int main( int argc, char **argv ) { //uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; @@ -678,6 +666,7 @@ int main( int argc, char **argv ) { logInit(); // get options and fill parameters from configuration file get_options (); //Command-line options, enb_properties + get_common_options(); #if T_TRACER T_Config_Init(); #endif @@ -691,18 +680,22 @@ int main( int argc, char **argv ) { itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); init_opt() ; + if(IS_SOFTMODEM_NOS1) + init_pdcp(); if (ouput_vcd) { vcd_signal_dumper_init("/tmp/openair_dump_nrUE.vcd"); } +/* #ifdef PDCP_USE_NETLINK netlink_init(); #if defined(PDCP_USE_NETLINK_QUEUES) pdcp_netlink_init(); #endif #endif -#ifndef PACKAGE_VERSION +*/ + #ifndef PACKAGE_VERSION # define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" #endif LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); @@ -728,10 +721,7 @@ int main( int argc, char **argv ) { PHY_vars_UE_g[0][CC_id] = init_nr_ue_vars(frame_parms[CC_id], 0,abstraction_flag); UE[CC_id] = PHY_vars_UE_g[0][CC_id]; - if (phy_test==1) - UE[CC_id]->mac_enabled = 0; - else - UE[CC_id]->mac_enabled = 1; + UE[CC_id]->mac_enabled = 1; UE[CC_id]->UE_scan = UE_scan; UE[CC_id]->UE_scan_carrier = UE_scan_carrier; @@ -740,13 +730,6 @@ int main( int argc, char **argv ) { UE[CC_id]->no_timing_correction = UE_no_timing_correction; printf("UE[%d]->mode = %d\n",CC_id,mode); - for (uint8_t i=0; i mac_enabled == 1) - UE[CC_id]->pdcch_vars[i][0]->crnti = 0x1234; - else - UE[CC_id]->pdcch_vars[i][0]->crnti = 0x1235; - } - UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; @@ -777,6 +760,7 @@ int main( int argc, char **argv ) { PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; #if defined(OAI_USRP) || defined(OAI_ADRV9371_ZC706) PHY_vars_UE_g[0][CC_id]->hw_timing_advance = timing_advance; + PHY_vars_UE_g[0][CC_id]->timing_advance = timing_advance; #else PHY_vars_UE_g[0][CC_id]->hw_timing_advance = 160; #endif @@ -784,7 +768,7 @@ int main( int argc, char **argv ) { // wait for end of program printf("TYPE TO TERMINATE\n"); - init_NR_UE(1); + init_NR_UE(1,rrc_config_path); while(true) sleep(3600); diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 6dd00276ed..fe448cf28e 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -1,6 +1,7 @@ #ifndef NR_UESOFTMODEM_H #define NR_UESOFTMODEM_H #include +#include #include "PHY/defs_nr_UE.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" #include @@ -50,41 +51,42 @@ {"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \ {"r" , CONFIG_HLP_PRB, 0, iptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT, 0}, \ {"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ - {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0} \ + {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0} \ } #define DEFAULT_DLF 2680000000 -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters common to eNodeB and UE */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters common to eNodeB and UE */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CMDLINE_PARAMS_DESC_UE { \ - {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)},\ - {"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ - {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ - {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ - {"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \ - {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ - {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ - {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ - {"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \ - {"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \ - {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:&do_forms, defintval:0, TYPE_INT, 0}, \ - {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \ - {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ - {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ - {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ - {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ - {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ - {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \ - {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \ - {"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \ - {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ - {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ - {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ - {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0}, \ - {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&UE_no_timing_correction, defintval:0, TYPE_INT, 0} \ + {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)},\ + {"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ + {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ + {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ + {"clock-source", CONFIG_HLP_EXCCLK, 0, iptr:&clock_source, defintval:0, TYPE_INT, 0}, \ + {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ + {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ + {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ + {"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \ + {"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \ + {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:&do_forms, defintval:0, TYPE_INT, 0}, \ + {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \ + {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ + {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ + {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ + {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ + {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ + {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \ + {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \ + {"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \ + {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ + {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ + {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ + {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0}, \ + {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&UE_no_timing_correction, defintval:0, TYPE_INT, 0}, \ + {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH,0, strptr:(char **)&rrc_config_path, defstrval:"./", TYPE_STRING, 0} \ } @@ -94,15 +96,12 @@ extern int T_dont_fork; // In nr-ue.c -extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, - openair0_config_t *openair0_cfg); +extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg); extern void fill_ue_band_info(void); -extern void init_NR_UE(int); +extern void init_NR_UE(int, char*); extern void reset_opp_meas(void); extern void print_opp_meas(void); void *UE_thread(void *arg); -PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms, - uint8_t UE_id, - uint8_t abstraction_flag); +PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag); extern tpool_t *Tpool; #endif diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h new file mode 100644 index 0000000000..f6ba3a6beb --- /dev/null +++ b/executables/softmodem-common.h @@ -0,0 +1,22 @@ +#ifndef SOFTMODEM_COMMON_H +#define SOFTMODEM_COMMON_H + +typedef struct { + uint64_t optmask; + THREAD_STRUCT thread_struct; + char rf_config_file[1024]; + int phy_test; + uint8_t usim_test; + int emulate_rf; + int wait_for_sync; //eNodeB only + int single_thread_flag; //eNodeB only + int chain_offset; + int numerology; + unsigned int start_msc; + uint32_t clock_source; + uint32_t timing_source; + int hw_timing_advance; + uint32_t send_dmrs_sync; +} softmodem_params_t; + +#endif diff --git a/executables/thread-common.h b/executables/thread-common.h new file mode 100644 index 0000000000..6f3af3cfc0 --- /dev/null +++ b/executables/thread-common.h @@ -0,0 +1,42 @@ +#ifndef THREAD_COMMON_H +#define THREAD_COMMON_H + +#include "PHY/defs_common.h" + +THREAD_STRUCT thread_struct; + +static inline void set_parallel_conf(char *parallel_conf) { + mapping config[]= { + FOREACH_PARALLEL(GENERATE_ENUMTXT) + {NULL,-1} + }; + thread_struct.parallel_conf = (PARALLEL_CONF_t)map_str_to_int(config, parallel_conf); + if (thread_struct.parallel_conf == -1 ) { + LOG_E(ENB_APP,"Impossible value: %s\n", parallel_conf); + thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; + } + printf("[CONFIG] parallel_conf is set to %d\n", thread_struct.parallel_conf); +} + +static inline void set_worker_conf(char *worker_conf) { + mapping config[]={ + FOREACH_WORKER(GENERATE_ENUMTXT) + {NULL, -1} + }; + thread_struct.worker_conf = (WORKER_CONF_t)map_str_to_int(config, worker_conf); + if (thread_struct.worker_conf == -1 ) { + LOG_E(ENB_APP,"Impossible value: %s\n", worker_conf); + thread_struct.worker_conf = WORKER_DISABLE ; + } + printf("[CONFIG] worker_conf is set to %d\n", thread_struct.worker_conf); +} + +static inline PARALLEL_CONF_t get_thread_parallel_conf(void) { + return thread_struct.parallel_conf; +} + +static inline WORKER_CONF_t get_thread_worker_conf(void) { + return thread_struct.worker_conf; +} + +#endif diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index a0574221f5..7ab8be5746 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -31,7 +31,7 @@ #include #include -#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" #include "nfapi_vnf_interface.h" #include "nfapi.h" #include "vendor_ext.h" @@ -1169,7 +1169,7 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return retval; } -int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) +int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_tti_request_t *dl_config_req) { nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; @@ -1177,9 +1177,9 @@ int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) int retval = nfapi_vnf_p7_nr_dl_config_req(p7_config, dl_config_req); - dl_config_req->dl_config_request_body.number_dci = 0; - dl_config_req->dl_config_request_body.number_pdu = 0; - dl_config_req->dl_config_request_body.number_pdsch_rnti = 0; + dl_config_req->dl_tti_request_body.nPDUs = 0; + dl_config_req->dl_tti_request_body.nGroup = 0; + if (retval!=0) { LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h index 32046d4982..cbcd26c3e3 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h @@ -8,6 +8,9 @@ #define FAPI_NR_MAX_NUM_ZP_CSI_RS_RESOURCE_PER_SET 16 #define FAPI_NR_MAX_NUM_CANDIDATE_BEAMS 16 #define FAPI_NR_MAX_RA_OCCASION_PER_CSIRS 64 +// Constants Defined in 38.213 +#define FAPI_NR_MAX_CORESET_PER_BWP 3 +#define FAPI_NR_MAX_SS_PER_CORESET 10 /// RX_IND @@ -41,8 +44,8 @@ #define FAPI_NR_DL_CONFIG_TYPE_DLSCH 0x02 -#define CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01 -#define CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02 +#define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01 +#define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02 #define PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE 0x01 #define PRECODER_GRANULARITY_ALL_CONTIGUOUS_RBS 0x02 @@ -51,8 +54,8 @@ #define FAPI_NR_UL_CONFIG_LIST_NUM 10 #define FAPI_NR_UL_CONFIG_TYPE_PRACH 0x01 -#define FAPI_NR_UL_CONFIG_TYPE_UCI 0x02 -#define FAPI_NR_UL_CONFIG_TYPE_ULSCH 0x03 +#define FAPI_NR_UL_CONFIG_TYPE_PUCCH 0x02 +#define FAPI_NR_UL_CONFIG_TYPE_PUSCH 0x03 #define FAPI_NR_UL_CONFIG_TYPE_SRS 0x04 diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 30020aaf23..c5b7a0a5ea 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -1,5 +1,4 @@ -/* - * Copyright 2017 Cisco Systems, Inc. +/*Copyright 2017 Cisco Systems, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,77 +31,7 @@ typedef signed char int8_t; */ -typedef struct { - uint8_t identifier_dci_formats ; // 0 IDENTIFIER_DCI_FORMATS: - uint8_t carrier_ind ; // 1 CARRIER_IND: 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213] - uint8_t sul_ind_0_1 ; // 2 SUL_IND_0_1: - uint8_t slot_format_ind ; // 3 SLOT_FORMAT_IND: size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213] - uint8_t pre_emption_ind ; // 4 PRE_EMPTION_IND: size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits - uint8_t block_number ; // 5 BLOCK_NUMBER: starting position of a block is determined by the parameter startingBitOfFormat2_3 - uint8_t close_loop_ind ; // 6 CLOSE_LOOP_IND: - uint8_t bandwidth_part_ind ; // 7 BANDWIDTH_PART_IND: - uint8_t short_message_ind ; // 8 SHORT_MESSAGE_IND: - uint8_t short_messages ; // 9 SHORT_MESSAGES: - uint16_t freq_dom_resource_assignment_UL; // 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered - // (NOTE 1) If DCI format 0_0 is monitored in common search space - // and if the number of information bits in the DCI format 0_0 prior to padding - // is larger than the payload size of the DCI format 1_0 monitored in common search space - // the bitwidth of the frequency domain resource allocation field in the DCI format 0_0 - // is reduced such that the size of DCI format 0_0 equals to the size of the DCI format 1_0 - uint16_t freq_dom_resource_assignment_DL; // 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - uint8_t time_dom_resource_assignment ; // 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - // where I the number of entries in the higher layer parameter pusch-AllocationList - uint8_t vrb_to_prb_mapping ; // 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - uint8_t prb_bundling_size_ind ; // 14 PRB_BUNDLING_SIZE_IND:0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214] - uint8_t rate_matching_ind ; // 15 RATE_MATCHING_IND: 0, 1, or 2 bits according to higher layer parameter rate-match-PDSCH-resource-set - uint8_t zp_csi_rs_trigger ; // 16 ZP_CSI_RS_TRIGGER: - uint8_t freq_hopping_flag ; // 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 - uint8_t tb1_mcs ; // 18 TB1_MCS: - uint8_t tb1_ndi ; // 19 TB1_NDI: - uint8_t tb1_rv ; // 20 TB1_RV: - uint8_t tb2_mcs ; // 21 TB2_MCS: - uint8_t tb2_ndi ; // 22 TB2_NDI: - uint8_t tb2_rv ; // 23 TB2_RV: - uint8_t mcs ; // 24 MCS: - uint8_t ndi ; // 25 NDI: - uint8_t rv ; // 26 RV: - uint8_t harq_process_number ; // 27 HARQ_PROCESS_NUMBER: - uint8_t dai ; // 28 DAI: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - // 2 if one serving cell is configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 bits are the counter DAI - // 0 otherwise - uint8_t first_dai ; // 29 FIRST_DAI: (1 or 2 bits) 1 bit for semi-static HARQ-ACK - uint8_t second_dai ; // 30 SECOND_DAI: (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks - uint8_t tb_scaling ; // 31 TB_SCALING: - uint8_t tpc_pusch ; // 32 TPC_PUSCH: - uint8_t tpc_pucch ; // 33 TPC_PUCCH: - uint8_t pucch_resource_ind ; // 34 PUCCH_RESOURCE_IND: - uint8_t pdsch_to_harq_feedback_time_ind ; // 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: - uint8_t srs_resource_ind ; // 36 SRS_RESOURCE_IND: - uint8_t precod_nbr_layers ; // 37 PRECOD_NBR_LAYERS: - uint8_t antenna_ports ; // 38 ANTENNA_PORTS: - uint8_t tci ; // 39 TCI: 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits - uint8_t srs_request ; // 40 SRS_REQUEST: - uint8_t tpc_cmd ; // 41 TPC_CMD: - uint8_t csi_request ; // 42 CSI_REQUEST: - uint8_t cbgti ; // 43 CBGTI: 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH - uint8_t cbgfi ; // 44 CBGFI: 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator - uint8_t ptrs_dmrs ; // 45 PTRS_DMRS: - uint8_t beta_offset_ind ; // 46 BETA_OFFSET_IND: - uint8_t dmrs_seq_ini ; // 47 DMRS_SEQ_INI: 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding - // is larger than the number of bits for DCI format 0_0 before padding; 0 bit otherwise - uint8_t ul_sch_ind ; // 48 UL_SCH_IND: value of "1" indicates UL-SCH shall be transmitted on the PUSCH and a value of "0" indicates UL-SCH shall not be transmitted on the PUSCH - uint16_t padding_nr_dci ; // 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space - // and if the number of information bits in the DCI format 0_0 prior to padding - // is less than the payload size of the DCI format 1_0 monitored in common search space - // zeros shall be appended to the DCI format 0_0 - // until the payload size equals that of the DCI format 1_0 - uint8_t sul_ind_0_0 ; // 50 SUL_IND_0_0: - uint8_t ra_preamble_index ; // 51 RA_PREAMBLE_INDEX: - uint8_t sul_ind_1_0 ; // 52 SUL_IND_1_0: - uint8_t ss_pbch_index ; // 53 SS_PBCH_INDEX - uint8_t prach_mask_index ; // 54 PRACH_MASK_INDEX - uint8_t reserved_nr_dci ; // 55 RESERVED_NR_DCI -} fapi_nr_dci_pdu_rel15_t; + @@ -121,16 +50,14 @@ typedef struct { typedef struct { /// frequency_domain_resource; - //uint32_t rb_start; - //uint32_t rb_end; - uint64_t frequency_domain_resource; - uint16_t rb_offset; - + uint8_t frequency_domain_resource[6]; + uint8_t StartSymbolIndex; uint8_t duration; - uint8_t cce_reg_mapping_type; // interleaved or noninterleaved - uint8_t cce_reg_interleaved_reg_bundle_size; // valid if CCE to REG mapping type is interleaved type - uint8_t cce_reg_interleaved_interleaver_size; // valid if CCE to REG mapping type is interleaved type - uint8_t cce_reg_interleaved_shift_index; // valid if CCE to REG mapping type is interleaved type + uint8_t CceRegMappingType; // interleaved or noninterleaved + uint8_t RegBundleSize; // valid if CCE to REG mapping type is interleaved type + uint8_t InterleaverSize; // valid if CCE to REG mapping type is interleaved type + uint8_t ShiftIndex; // valid if CCE to REG mapping type is interleaved type + uint8_t CoreSetType; uint8_t precoder_granularity; uint16_t pdcch_dmrs_scrambling_id; @@ -155,13 +82,16 @@ typedef struct { int n_CCE; // N_CCE is L, or number of CCEs for DCI int N_CCE; - fapi_nr_dci_pdu_rel15_t dci; + uint8_t payloadSize; + uint8_t payloadBits[16]; + //fapi_nr_dci_pdu_rel15_t dci; } fapi_nr_dci_indication_pdu_t; /// typedef struct { - uint32_t sfn_slot; + uint16_t SFN; + uint8_t slot; uint16_t number_of_dcis; fapi_nr_dci_indication_pdu_t dci_list[10]; } fapi_nr_dci_indication_t; @@ -197,11 +127,11 @@ typedef struct { } fapi_nr_rx_indication_body_t; /// -#define FAPI_RX_IND_MAX_PDU 100 +#define NFAPI_RX_IND_MAX_PDU 100 typedef struct { uint32_t sfn_slot; uint16_t number_pdus; - fapi_nr_rx_indication_body_t rx_indication_body[FAPI_RX_IND_MAX_PDU]; + fapi_nr_rx_indication_body_t rx_indication_body[NFAPI_RX_IND_MAX_PDU]; } fapi_nr_rx_indication_t; typedef struct { @@ -224,22 +154,22 @@ typedef struct { fapi_nr_tx_request_body_t *tx_request_body; } fapi_nr_tx_request_t; -typedef struct { - uint8_t preamble_index; - uint8_t prach_configuration_index; - uint16_t preamble_length; - uint8_t power_ramping_step; - uint16_t preamble_received_target_power; - uint8_t msg1_fdm; - uint8_t msg1_frequency_start; - uint8_t zero_correlation_zone_config; - uint8_t subcarrier_spacing; - uint8_t restrictedset_config; - uint16_t root_sequence_index; - uint16_t rsrp_threshold_ssb; - uint16_t rsrp_threshold_sul; - uint16_t prach_freq_offset; -} fapi_nr_ul_config_prach_pdu; + typedef struct { + uint8_t preamble_index; + uint8_t prach_configuration_index; + uint16_t preamble_length; + uint8_t power_ramping_step; + uint16_t preamble_received_target_power; + uint8_t msg1_fdm; + uint8_t msg1_frequency_start; + uint8_t zero_correlation_zone_config; + uint8_t subcarrier_spacing; + uint8_t restrictedset_config; + uint16_t root_sequence_index; + uint16_t rsrp_threshold_ssb; + uint16_t rsrp_threshold_sul; + uint16_t prach_freq_offset; + } fapi_nr_ul_config_prach_pdu; typedef struct { @@ -322,7 +252,7 @@ typedef struct { // pathlossReferenceRSs SEQUENCE (SIZE (1..maxNrofPUCCH-PathlossReferenceRSs)) OF PUCCH-PathlossReferenceRS OPTIONAL, -- Need M int8_t twoPUCCH_PC_AdjustmentStates; - } fapi_nr_ul_config_uci_pdu; + } fapi_nr_ul_config_pucch_pdu; typedef enum {pusch_freq_hopping_disabled = 0 , pusch_freq_hopping_enabled = 1}pusch_freq_hopping_t; typedef struct{ @@ -352,39 +282,23 @@ typedef struct { uint8_t maxCodeBlockGroupsPerTransportBlock; uint8_t ptrs_dmrs_association_port; uint8_t beta_offset_ind; - } fapi_nr_ul_config_ulsch_pdu_rel15_t; + } fapi_nr_ul_config_pusch_pdu_rel15_t; typedef struct { uint16_t rnti; - fapi_nr_ul_config_ulsch_pdu_rel15_t ulsch_pdu_rel15; -} fapi_nr_ul_config_ulsch_pdu; + fapi_nr_ul_config_pusch_pdu_rel15_t ulsch_pdu_rel15; +} fapi_nr_ul_config_pusch_pdu; typedef struct { } fapi_nr_ul_config_srs_pdu; -// nFAPI enums -typedef enum { - FAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE = 0, - FAPI_NR_DL_CONFIG_BCH_PDU_TYPE, - FAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE, - FAPI_NR_DL_CONFIG_PCH_PDU_TYPE, -} fapi_nr_dl_config_pdu_type_e; - -// nFAPI enums -typedef enum { - FAPI_NR_UL_CONFIG_PRACH_PDU_TYPE = 0, - FAPI_NR_UL_CONFIG_ULSCH_PDU_TYPE, - FAPI_NR_UL_CONFIG_UCI_PDU_TYPE, - FAPI_NR_UL_CONFIG_SRS_PDU_TYPE, -} fapi_nr_ul_config_pdu_type_e; - typedef struct { uint8_t pdu_type; union { fapi_nr_ul_config_prach_pdu prach_config_pdu; - fapi_nr_ul_config_uci_pdu uci_config_pdu; - fapi_nr_ul_config_ulsch_pdu ulsch_config_pdu; + fapi_nr_ul_config_pucch_pdu pucch_config_pdu; + fapi_nr_ul_config_pusch_pdu ulsch_config_pdu; fapi_nr_ul_config_srs_pdu srs_config_pdu; }; } fapi_nr_ul_config_request_pdu_t; @@ -398,16 +312,15 @@ typedef struct { typedef struct { uint16_t rnti; - + uint16_t BWPSize; + uint16_t BWPStart; + uint8_t SubcarrierSpacing; fapi_nr_coreset_t coreset; - uint16_t N_RB_BWP; - uint32_t duration; - uint8_t number_of_candidates[5]; // aggregation level 1, 2, 4, 8, 16 - uint16_t monitoring_symbols_within_slot; - // DCI foramt-specific - uint8_t format_2_0_number_of_candidates[5]; // aggregation level 1, 2, 4, 8, 16 - uint8_t format_2_3_monitorying_periodicity; - uint8_t format_2_3_number_of_candidates; + uint8_t number_of_candidates; + uint16_t CCE[64]; + uint8_t L[64]; + uint8_t dci_length; + uint8_t dci_format; } fapi_nr_dl_config_dci_dl_pdu_rel15_t; typedef struct { @@ -420,12 +333,16 @@ typedef struct{ typedef enum{vrb_to_prb_mapping_non_interleaved = 0, vrb_to_prb_mapping_interleaved = 1} vrb_to_prb_mapping_t; //typedef fapi_nr_dci_pdu_rel15_t fapi_nr_dl_config_dlsch_pdu_rel15_t; typedef struct { - uint8_t bandwidth_part_ind; + uint16_t BWPSize; + uint16_t BWPStart; + uint8_t SubcarrierSpacing; uint16_t number_rbs; uint16_t start_rb; uint8_t frame_offset; uint16_t number_symbols; uint16_t start_symbol; + uint16_t dlDmrsSymbPos; + uint8_t dmrsConfigType; uint8_t prb_bundling_size_ind; uint8_t rate_matching_ind; uint8_t zp_csi_rs_trigger; @@ -452,20 +369,6 @@ typedef struct { // to be check the fields needed to L1 with NR_DL_UE_HARQ_t and NR_UE_DLSCH_t } fapi_nr_dl_config_dlsch_pdu_rel15_t; -typedef struct { - - uint8_t subcarrier_spacing_common; - uint8_t ssb_subcarrier_offset; - uint8_t dmrs_type_a_position; - uint8_t pdcch_config_sib1; - uint8_t cell_barred; - uint8_t intra_frequency_reselection; - - uint16_t system_frame_number; - uint8_t ssb_index; - uint8_t half_frame_bit; -} fapi_nr_dl_config_bch_pdu; - typedef struct { uint16_t rnti; fapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config_rel15; @@ -474,7 +377,6 @@ typedef struct { typedef struct { uint8_t pdu_type; union { - fapi_nr_dl_config_bch_pdu bch_config_pdu; fapi_nr_dl_config_dci_pdu dci_config_pdu; fapi_nr_dl_config_dlsch_pdu dlsch_config_pdu; }; @@ -492,154 +394,6 @@ typedef struct { // -typedef struct { - uint8_t numerology_index_mu; - uint8_t duplex_mode; - uint8_t dl_cyclic_prefix_type; - uint8_t ul_cyclic_prefix_type; -} fapi_nr_subframe_config_t; - -typedef struct { - uint16_t dl_carrier_bandwidth; - uint16_t ul_carrier_bandwidth; - uint16_t dl_absolutefrequencypointA; - uint16_t ul_absolutefrequencypointA; - uint16_t dl_offsettocarrier; - uint16_t ul_offsettocarrier; - uint16_t dl_subcarrierspacing; - uint16_t ul_subcarrierspacing; - uint16_t dl_specificcarrier_k0; - uint16_t ul_specificcarrier_k0; - uint16_t NIA_subcarrierspacing; -} fapi_nr_rf_config_t; - -typedef struct { - uint16_t physical_cell_id; - uint8_t half_frame_index; - uint16_t ssb_subcarrier_offset; - uint16_t ssb_sib1_position_in_burst; // in sib1 - uint64_t ssb_scg_position_in_burst; // in servingcellconfigcommon - uint8_t ssb_periodicity; - uint16_t ss_pbch_block_power; - uint16_t n_ssb_crb; -} fapi_nr_sch_config_t; - -typedef struct { - uint16_t dl_bandwidth; - uint16_t ul_bandwidth; - uint16_t dl_offset; - uint16_t ul_offset; - uint8_t dl_subcarrierSpacing; - uint8_t ul_subcarrierSpacing; -} fapi_nr_initialBWP_config_t; - -#define FAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS 16 -#define FAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS 16 - -typedef struct { - uint16_t dmrs_TypeA_Position; - uint16_t num_PDSCHTimeDomainResourceAllocations; - uint16_t PDSCHTimeDomainResourceAllocation_k0[FAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS]; - uint16_t PDSCHTimeDomainResourceAllocation_mappingType[FAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS]; - uint16_t PDSCHTimeDomainResourceAllocation_startSymbolAndLength[FAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS]; -} fapi_nr_pdsch_config_t; - -typedef struct { - uint16_t prach_RootSequenceIndex; ///// L1 parameter 'PRACHRootSequenceIndex' - uint16_t prach_msg1_SubcarrierSpacing; ///// L1 parameter 'prach-Msg1SubcarrierSpacing' - uint16_t restrictedSetConfig; - uint16_t msg3_transformPrecoding; ///// L1 parameter 'msg3-tp' - uint16_t ssb_perRACH_OccasionAndCB_PreamblesPerSSB; - uint16_t ra_ContentionResolutionTimer; - uint16_t rsrp_ThresholdSSB; - /////////////////--------------------NR RACH-ConfigGeneric--------------------///////////////// - uint16_t prach_ConfigurationIndex; ///// L1 parameter 'PRACHConfigurationIndex' - uint16_t prach_msg1_FDM; ///// L1 parameter 'prach-FDM' - uint16_t prach_msg1_FrequencyStart; ///// L1 parameter 'prach-frequency-start' - uint16_t zeroCorrelationZoneConfig; - uint16_t preambleReceivedTargetPower; - uint16_t preambleTransMax; - uint16_t powerRampingStep; - uint16_t ra_ResponseWindow; -} fapi_nr_rach_config_t; - -typedef struct { - uint16_t groupHoppingEnabledTransformPrecoding; ///// L1 parameter 'Group-hopping-enabled-Transform-precoding' - uint16_t msg3_DeltaPreamble; ///// L1 parameter 'Delta-preamble-msg3' - uint16_t p0_NominalWithGrant; ///// L1 parameter 'p0-nominal-pusch-withgrant' - uint16_t dmrs_TypeA_Position; - uint16_t num_PUSCHTimeDomainResourceAllocations; - uint16_t PUSCHTimeDomainResourceAllocation_k2[FAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS]; ///// L1 parameter 'K2' - uint16_t PUSCHTimeDomainResourceAllocation_mappingType[FAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS]; ///// L1 parameter 'Mapping-type' - uint16_t PUSCHTimeDomainResourceAllocation_startSymbolAndLength[FAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS]; -} fapi_nr_pusch_config_t; - -typedef struct { - uint8_t pucch_resource_common; - uint16_t pucch_GroupHopping; ///// L1 parameter 'PUCCH-GroupHopping' - uint8_t hopping_id; - uint16_t p0_nominal; ///// L1 parameter 'p0-nominal-pucch' -} fapi_nr_pucch_config_t; - -typedef struct { - uint8_t controlResourceSetZero; - uint8_t searchSpaceZero; - - // fapi_nr_SearchSpace_t sib1searchSpace; - // fapi_nr_SearchSpace_t sibssearchSpace; - // fapi_nr_SearchSpace_t ra_SearchSpace; -} fapi_nr_pdcch_config_t; - -typedef struct { -//NR TDD-UL-DL-ConfigCommon ///// L1 parameter 'UL-DL-configuration-common' - uint16_t referenceSubcarrierSpacing; ///// L1 parameter 'reference-SCS' - uint16_t dl_ul_periodicity; ///// L1 parameter 'DL-UL-transmission-periodicity' - uint16_t nrofDownlinkSlots; ///// L1 parameter 'number-of-DL-slots' - uint16_t nrofDownlinkSymbols; ///// L1 parameter 'number-of-DL-symbols-common' - uint16_t nrofUplinkSlots; ///// L1 parameter 'number-of-UL-slots' - uint16_t nrofUplinkSymbols; ///// L1 parameter 'number-of-UL-symbols-common' - uint16_t Pattern2Present; - uint16_t Pattern2_dl_ul_periodicity; ///// L1 parameter 'DL-UL-transmission-periodicity' - uint16_t Pattern2_nrofDownlinkSlots; ///// L1 parameter 'number-of-DL-slots' - uint16_t Pattern2_nrofDownlinkSymbols; ///// L1 parameter 'number-of-DL-symbols-common' - uint16_t Pattern2_nrofUplinkSlots; ///// L1 parameter 'number-of-UL-slots' - uint16_t Pattern2_nrofUplinkSymbols; ///// L1 parameter 'number-of-UL-symbols-common' -} fapi_nr_tdd_ul_dl_config_t; - -#define FAPI_MAX_NUM_RF_BANDS 16 -typedef struct { - uint16_t number_rf_bands; - uint16_t rf_band[FAPI_MAX_NUM_RF_BANDS]; -} fapi_rf_bands_t; - -typedef struct -{ - fapi_rf_bands_t rf_bands; - - uint32_t nrarfcn; - - // nfapi_nmm_frequency_bands_t nmm_gsm_frequency_bands; - // nfapi_nmm_frequency_bands_t nmm_umts_frequency_bands; - // nfapi_nmm_frequency_bands_t nmm_lte_frequency_bands; - // nfapi_uint8_tlv_t nmm_uplink_rssi_supported; - -} fapi_nr_fapi_t; - -typedef struct { - fapi_nr_fapi_t fapi_config; - fapi_nr_subframe_config_t subframe_config; - fapi_nr_rf_config_t rf_config; - fapi_nr_sch_config_t sch_config; - fapi_nr_initialBWP_config_t initialBWP_config; - fapi_nr_pdsch_config_t pdsch_config; - fapi_nr_rach_config_t rach_config; - fapi_nr_pusch_config_t pusch_config; - fapi_nr_pucch_config_t pucch_config; - fapi_nr_pdcch_config_t pdcch_config; - fapi_nr_tdd_ul_dl_config_t tdd_ul_dl_config; - // fapi_nr_ratematchpattern_t ratematchpattern; - // fapi_nr_ratematchpattern_lte_crs_t ratematchpattern_lte_crs; -} fapi_nr_config_request_t; typedef struct { fapi_nr_coreset_t coreset; @@ -723,6 +477,19 @@ typedef struct { uint8_t p0_nominal; } fapi_nr_pucch_config_common_t; +typedef struct { + + uint8_t subcarrier_spacing_common; + uint8_t ssb_subcarrier_offset; + uint8_t dmrs_type_a_position; + uint8_t pdcch_config_sib1; + uint8_t cell_barred; + uint8_t intra_frequency_reselection; + + uint16_t system_frame_number; + uint8_t ssb_index; + uint8_t half_frame_bit; +} fapi_nr_pbch_config_t; typedef struct { @@ -859,6 +626,7 @@ typedef struct { fapi_nr_pdsch_config_dedicated_t pdsch_config_dedicated; fapi_nr_sps_config_t sps_config; fapi_nr_radio_link_monitoring_config_t radio_link_monitoring_config; + } fapi_nr_dl_bwp_dedicated_config_t; typedef struct { @@ -1072,4 +840,18 @@ typedef struct { #define FAPI_NR_CONFIG_REQUEST_MASK_DL_BWP_DEDICATED 0x08 #define FAPI_NR_CONFIG_REQUEST_MASK_UL_BWP_DEDICATED 0x10 +typedef struct { + uint32_t config_mask; + + fapi_nr_pbch_config_t pbch_config; // MIB + + fapi_nr_dl_bwp_common_config_t dl_bwp_common; + fapi_nr_dl_bwp_dedicated_config_t dl_bwp_dedicated; + + fapi_nr_ul_bwp_common_config_t ul_bwp_common; + fapi_nr_ul_bwp_dedicated_config_t ul_bwp_dedicated; + +} fapi_nr_config_request_t; + #endif + diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h index 525baef291..5f12fc55b9 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h @@ -11,48 +11,16 @@ #include "nfapi_interface.h" - #define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5 #define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64 #define NFAPI_NR_MAX_NB_CORESETS 12 #define NFAPI_NR_MAX_NB_SEARCH_SPACES 40 -// Extension to the generic structures for single tlv values -typedef struct { - nfapi_tl_t tl; - int32_t value; -} nfapi_int32_tlv_t; -typedef struct { - nfapi_tl_t tl; - uint32_t value; -} nfapi_uint32_tlv_t; - -/*typedef struct { - nfapi_tl_t tl; - int64_t value; -} nfapi_int64_tlv_t;*/ - -typedef struct { - nfapi_tl_t tl; - uint64_t value; -} nfapi_uint64_tlv_t; // nFAPI enums -typedef enum { - NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE = 0, - NFAPI_NR_DL_CONFIG_BCH_PDU_TYPE, - NFAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE, - NFAPI_NR_DL_CONFIG_PCH_PDU_TYPE, -} nfapi_nr_dl_config_pdu_type_e; -// nFAPI enums -typedef enum { - NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE = 0, - NFAPI_NR_UL_CONFIG_ULSCH_PDU_TYPE, - NFAPI_NR_UL_CONFIG_UCI_PDU_TYPE, - NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE, -} nfapi_nr_ul_config_pdu_type_e; + //These TLVs are used exclusively by nFAPI typedef struct @@ -111,37 +79,6 @@ typedef struct // P5 Message Structures -typedef struct{ - nfapi_tl_t tl; - uint16_t corset_ID; ///// L1 parameter 'CORESET-ID' - uint16_t freq_dom; ///// L1 parameter 'CORESET-freq-dom' - uint16_t duration; ///// L1 parameter 'CORESET-time-duration' - uint16_t reg_type; ///// L1 parameter 'CORESET-CCE-REG-mapping-type' - uint16_t reg_bundlesize; ///// L1 parameter 'CORESET-REG-bundle-size' - uint16_t interleaversize; ///// L1 parameter 'CORESET-interleaver-size' - uint16_t shiftindex; ///// L1 parameter 'CORESET-shift-index' - uint16_t precodergranularity; ///// L1 parameter 'CORESET-precoder-granuality' - uint16_t tci_stateId; ///// L1 parameter 'TCI-StatesPDCCH' - uint16_t tci_present; ///// L1 parameter 'TCI-PresentInDCI' - uint16_t dmrs_scramblingID; ///// L1 parameter 'PDCCH-DMRS-Scrambling-ID' -} nfapi_nr_ControlResourcesSet_t; - -typedef struct{ - nfapi_tl_t tl; - nfapi_nr_ControlResourcesSet_t coreset; - uint16_t monitoringSlotPeriodicityAndOffset; ///// L1 parameters 'Montoring-periodicity-PDCCH-slot' - uint16_t monitoringSymbolsWithinSlot; ///// L1 parameter 'Montoring-symbols-PDCCH-within-slot' - uint16_t nrofCand_aggLevel1; ///// L1 parameter 'Aggregation-level-1' - uint16_t nrofCand_aggLevel2; ///// L1 parameter 'Aggregation-level-2' - uint16_t nrofCand_aggLevel4; ///// L1 parameter 'Aggregation-level-4' - uint16_t nrofCand_aggLevel8; ///// L1 parameter 'Aggregation-level-8' - uint16_t nrofCand_aggLevel16; ///// L1 parameter 'Aggregation-level-16' - uint16_t sfi_agg_fmt2_0; ///// L1 parameters 'SFI-Num-PDCCH-cand' and 'SFI-Aggregation-Level' - uint16_t monitoringperiodicity_fmt2_3; ///// L1 parameter 'SRS-monitoring-periodicity' - uint16_t nrof_candidates_fmt_2_3; ///// L1 parameter 'SRS-Num-PDCCH-cand' -} nfapi_nr_SearchSpace_t; - - typedef struct { nfapi_uint16_tlv_t numerology_index_mu; nfapi_uint16_tlv_t duplex_mode; @@ -457,13 +394,9 @@ typedef enum { NFAPI_NR_MCS_TABLE_QAM256 } nfapi_nr_pdsch_mcs_table_e; -typedef enum { - NFAPI_NR_DMRS_TYPE1=0, - NFAPI_NR_DMRS_TYPE2 -} nfapi_nr_dmrs_type_e; - // P7 Sub Structures +/* typedef struct { nfapi_tl_t tl; @@ -526,9 +459,12 @@ uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 uint16_t padding; } nfapi_nr_dl_config_dci_dl_pdu_rel15_t; - +*/ //#define NFAPI_NR_DL_CONFIG_REQUEST_DCI_DL_PDU_REL15_TAG 0x???? + + +/* typedef struct{ nfapi_tl_t tl; uint8_t coreset_id; @@ -563,11 +499,13 @@ typedef struct{ uint16_t number_of_candidates[NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS]; } nfapi_nr_search_space_t; + typedef struct { nfapi_tl_t tl; uint16_t rnti; uint8_t rnti_type; uint8_t dci_format; + uint16_t cce_index; /// Number of CRB in BWP that this DCI configures uint16_t n_RB_BWP; uint8_t config_type; @@ -592,108 +530,7 @@ typedef struct { nfapi_bf_vector_t bf_vector; } nfapi_nr_dl_config_pdcch_parameters_rel15_t; -typedef struct { - nfapi_tl_t tl; - uint16_t length; - int16_t pdu_index; - uint16_t transmission_power; -} nfapi_nr_dl_config_bch_pdu_rel15_t; -#define NFAPI_NR_DL_CONFIG_REQUEST_BCH_PDU_REL15_TAG 0x5025 - -typedef struct { - nfapi_nr_dl_config_bch_pdu_rel15_t bch_pdu_rel15; -} nfapi_nr_dl_config_bch_pdu; - -typedef struct { - nfapi_tl_t tl; - uint16_t length; - uint8_t pdu_index; - uint16_t rnti; - uint16_t nb_mod_symbols; - uint8_t time_allocation_type; - uint8_t freq_allocation_type; - uint16_t start_prb; - uint16_t n_prb; - uint8_t start_symbol; - uint8_t nb_symbols; - uint8_t mcs_idx; - uint8_t ndi; - uint8_t nb_codewords; - uint8_t nb_layers; - uint16_t coding_rate; - uint8_t modulation; - uint8_t modulation_order; - uint16_t transport_block_size; - uint8_t dmrs_Type; - uint8_t dmrs_TypeA_Position; - uint8_t dmrs_maxLength; - uint8_t dmrs_AdditionalPosition; - uint8_t time_alloc_list_flag; - uint8_t time_alloc_list; - uint8_t mapping_type; - uint8_t rbg_list; - uint8_t virtual_resource_block_assignment_flag; - uint32_t resource_block_coding; - uint8_t redundancy_version; - uint8_t transport_blocks; - uint8_t transmission_scheme; - uint8_t number_of_subbands; - uint8_t codebook_index[NFAPI_MAX_NUM_SUBBANDS]; - uint8_t ue_category_capacity; - uint8_t x_overhead; - uint8_t pa; - uint8_t delta_power_offset_index; - uint8_t ngap; - uint8_t transmission_mode; - uint8_t num_bf_prb_per_subband; - uint8_t num_bf_vector; - nfapi_bf_vector_t bf_vector[NFAPI_MAX_BF_VECTORS]; -}nfapi_nr_dl_config_dlsch_pdu_rel15_t; -#define NFAPI_NR_DL_CONFIG_REQUEST_DLSCH_PDU_REL15_TAG - -typedef struct { - nfapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_pdu_rel15; -} nfapi_nr_dl_config_dlsch_pdu; - -typedef struct { - nfapi_tl_t tl; - nfapi_nr_search_space_t pagingSearchSpace; - nfapi_nr_coreset_t pagingControlResourceSets; -}nfapi_nr_dl_config_pch_pdu_rel15_t; - -typedef struct { - nfapi_nr_dl_config_dci_dl_pdu_rel15_t dci_dl_pdu_rel15; - nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params_rel15; -} nfapi_nr_dl_config_dci_dl_pdu; - - -typedef struct { - uint8_t pdu_type; - uint8_t pdu_size; - - union { - nfapi_nr_dl_config_dci_dl_pdu dci_dl_pdu; - nfapi_nr_dl_config_bch_pdu_rel15_t bch_pdu_rel15; - nfapi_nr_dl_config_dlsch_pdu dlsch_pdu; - nfapi_nr_dl_config_pch_pdu_rel15_t pch_pdu_rel15; - }; -} nfapi_nr_dl_config_request_pdu_t; - - -typedef struct { - nfapi_tl_t tl; - uint8_t number_dci; - uint8_t number_pdu; - uint8_t number_pdsch_rnti; - nfapi_nr_dl_config_request_pdu_t *dl_config_pdu_list; -} nfapi_nr_dl_config_request_body_t; - -typedef struct { - nfapi_p7_message_header_t header; - uint16_t sfn_sf; - nfapi_nr_dl_config_request_body_t dl_config_request_body; - nfapi_vendor_extension_tlv_t vendor_extension; -} nfapi_nr_dl_config_request_t; +*/ typedef enum {nr_pusch_freq_hopping_disabled = 0 , @@ -716,6 +553,7 @@ typedef struct { nr_pusch_freq_hopping_t pusch_freq_hopping; uint8_t mcs; uint8_t Qm; + uint16_t R; uint8_t ndi; uint8_t rv; int8_t accumulated_delta_PUSCH; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h new file mode 100644 index 0000000000..ee1550a5bb --- /dev/null +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -0,0 +1,1646 @@ +/* + nfapi_nr_interface.h + ------------------- + AUTHOR : Chenyu Zhang, Florian Kaltenberger + COMPANY : BUPT, EURECOM + EMAIL : octopus@bupt.edu.cn, florian.kaltenberger@eurecom.fr +*/ + +#ifndef _NFAPI_NR_INTERFACE_SCF_H_ +#define _NFAPI_NR_INTERFACE_SCF_H_ + +#include "stddef.h" +#include "nfapi_interface.h" + +#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5 +#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64 +#define NFAPI_NR_MAX_NB_CORESETS 12 +#define NFAPI_NR_MAX_NB_SEARCH_SPACES 40 + +#define NFAPI_MAX_NUM_UL_UE_PER_GROUP 6 +#define NFAPI_MAX_NUM_UL_PDU 8 +#define NFAPI_MAX_NUM_GROUPS 8 +#define NFAPI_MAX_NUM_CB 8 + +// Extension to the generic structures for single tlv values +typedef struct { + nfapi_tl_t tl; + int32_t value; +} nfapi_int32_tlv_t; + +typedef struct { + nfapi_tl_t tl; + uint32_t value; +} nfapi_uint32_tlv_t; + +typedef struct { + nfapi_tl_t tl; + int64_t value; +} nfapi_int64_tlv_t; + +typedef struct { + nfapi_tl_t tl; + uint64_t value; +} nfapi_uint64_tlv_t; + +typedef enum { + NFAPI_NR_DMRS_TYPE1=0, + NFAPI_NR_DMRS_TYPE2 +} nfapi_nr_dmrs_type_e; + + +typedef struct { + /// Value: 0 -> 1, 0: Payload is carried directly in the value field, 1: Pointer to payload is in the value field + uint16_t tag; + /// Length of the actual payload in bytes, without the padding bytes Value: 0 → 65535 + uint16_t length; + union { + uint32_t *ptr; + uint32_t direct[16384]; + } value; +} nfapi_nr_tx_data_request_tlv_t; + + +// 2019.8 +// SCF222_5G-FAPI_PHY_SPI_Specificayion.pdf Section 3.2 + +//PHY API message types + +typedef enum { + NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST= 0x00, + NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE= 0x01, + NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST= 0x02, + NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE=0X03, + NFAPI_NR_PHY_MSG_TYPE_START_REQUEST= 0X04, + NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST= 0X05, + NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION=0X06, + NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION=0X07, + //RESERVED 0X08 ~ 0X7F + NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST= 0X80, + NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST= 0X81, + NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION=0X82, + NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST= 0X83, + NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST=0X54, + NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION=0X85, + NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION= 0X86, + NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION= 0X87, + NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION= 0X88, + NFAPI_NR_PHY_MSG_TYPE_PACH_INDICATION= 0X89 + //RESERVED 0X8a ~ 0xff +} nfapi_nr_phy_msg_type_e; + +// SCF222_5G-FAPI_PHY_SPI_Specificayion.pdf Section 3.3 + +//3.3.1 PARAM + +//same with nfapi_param_request_t +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_param_request_t; + +typedef enum { + NFAPI_NR_PARAM_MSG_OK = 0, + NFAPI_NR_PARAM_MSG_INVALID_STATE + +} nfapi_nr_param_errors_e; + +/*typedef struct { + nfapi_nr_param_errors_e error_code; + //Number of TLVs contained in the message body. + uint8_t number_of_tlvs; + nfapi_nr_param_tlv_t TLV; +} nfapi_nr_param_response_t;*/ + + +//PARAM and CONFIG TLVs are used in the PARAM and CONFIG message exchanges, respectively + + +//nfapi_nr_param_tlv_format_t cell param ~ measurement_param: + +//table 3-9 + +#define NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG 0x0001 +#define NFAPI_NR_PARAM_TLV_PHY_STATE_TAG 0x0002 +#define NFAPI_NR_PARAM_TLV_SKIP_BLANK_DL_CONFIG_TAG 0x0003 +#define NFAPI_NR_PARAM_TLV_SKIP_BLANK_UL_CONFIG_TAG 0x0004 +#define NFAPI_NR_PARAM_TLV_NUM_CONFIG_TLVS_TO_REPORT_TAG 0x0005 +#define NFAPI_NR_PARAM_TLV_CYCLIC_PREFIX_TAG 0x0006 +#define NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_DL_TAG 0x0007 +#define NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_DL_TAG 0x0008 +#define NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_UL_TAG 0x0009 +#define NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_UL_TAG 0x000A +#define NFAPI_NR_PARAM_TLV_CCE_MAPPING_TYPE_TAG 0x000B +#define NFAPI_NR_PARAM_TLV_CORESET_OUTSIDE_FIRST_3_OFDM_SYMS_OF_SLOT_TAG 0x000C +#define NFAPI_NR_PARAM_TLV_PRECODER_GRANULARITY_CORESET_TAG 0x000D +#define NFAPI_NR_PARAM_TLV_PDCCH_MU_MIMO_TAG 0x000E +#define NFAPI_NR_PARAM_TLV_PDCCH_PRECODER_CYCLING_TAG 0x000F +#define NFAPI_NR_PARAM_TLV_MAX_PDCCHS_PER_SLOT_TAG 0x0010 +#define NFAPI_NR_PARAM_TLV_PUCCH_FORMATS_TAG 0x0011 +#define NFAPI_NR_PARAM_TLV_MAX_PUCCHS_PER_SLOT_TAG 0x0012 +#define NFAPI_NR_PARAM_TLV_PDSCH_MAPPING_TYPE_TAG 0x0013 +#define NFAPI_NR_PARAM_TLV_PDSCH_ALLOCATION_TYPES_TAG 0x0014 +#define NFAPI_NR_PARAM_TLV_PDSCH_VRB_TO_PRB_MAPPING_TAG 0x0015 +#define NFAPI_NR_PARAM_TLV_PDSCH_CBG_TAG 0x0016 +#define NFAPI_NR_PARAM_TLV_PDSCH_DMRS_CONFIG_TYPES_TAG 0x0017 +#define NFAPI_NR_PARAM_TLV_PDSCH_DMRS_MAX_LENGTH_TAG 0x0018 +#define NFAPI_NR_PARAM_TLV_PDSCH_DMRS_ADDITIONAL_POS_TAG 0x0019 +#define NFAPI_NR_PARAM_TLV_MAX_PDSCH_S_YBS_PER_SLOT_TAG 0x001A +#define NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_PDSCH_TAG 0x001B +#define NFAPI_NR_PARAM_TLV_SUPPORTED_MAX_MODULATION_ORDER_DL_TAG 0x001C +#define NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_DL_TAG 0x001D +#define NFAPI_NR_PARAM_TLV_PDSCH_DATA_IN_DMRS_SYMBOLS_TAG 0x001E +#define NFAPI_NR_PARAM_TLV_PREMPTION_SUPPORT_TAG 0x001F +#define NFAPI_NR_PARAM_TLV_PDSCH_NON_SLOT_SUPPORT_TAG 0x0020 +#define NFAPI_NR_PARAM_TLV_UCI_MUX_ULSCH_IN_PUSCH_TAG 0x0021 +#define NFAPI_NR_PARAM_TLV_UCI_ONLY_PUSCH_TAG 0x0022 +#define NFAPI_NR_PARAM_TLV_PUSCH_FREQUENCY_HOPPING_TAG 0x0023 +#define NFAPI_NR_PARAM_TLV_PUSCH_DMRS_CONFIG_TYPES_TAG 0x0024 +#define NFAPI_NR_PARAM_TLV_PUSCH_DMRS_MAX_LEN_TAG 0x0025 +#define NFAPI_NR_PARAM_TLV_PUSCH_DMRS_ADDITIONAL_POS_TAG 0x0026 +#define NFAPI_NR_PARAM_TLV_PUSCH_CBG_TAG 0x0027 +#define NFAPI_NR_PARAM_TLV_PUSCH_MAPPING_TYPE_TAG 0x0028 +#define NFAPI_NR_PARAM_TLV_PUSCH_ALLOCATION_TYPES_TAG 0x0029 +#define NFAPI_NR_PARAM_TLV_PUSCH_VRB_TO_PRB_MAPPING_TAG 0x002A +#define NFAPI_NR_PARAM_TLV_PUSCH_MAX_PTRS_PORTS_TAG 0x002B +#define NFAPI_NR_PARAM_TLV_MAX_PDUSCHS_TBS_PER_SLOT_TAG 0x002C +#define NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_NON_CB_PUSCH_TAG 0x002D +#define NFAPI_NR_PARAM_TLV_SUPPORTED_MODULATION_ORDER_UL_TAG 0x002E +#define NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_UL_TAG 0x002F +#define NFAPI_NR_PARAM_TLV_DFTS_OFDM_SUPPORT_TAG 0x0030 +#define NFAPI_NR_PARAM_TLV_PUSCH_AGGREGATION_FACTOR_TAG 0x0031 +#define NFAPI_NR_PARAM_TLV_PRACH_LONG_FORMATS_TAG 0x0032 +#define NFAPI_NR_PARAM_TLV_PRACH_SHORT_FORMATS_TAG 0x0033 +#define NFAPI_NR_PARAM_TLV_PRACH_RESTRICTED_SETS_TAG 0x0034 +#define NFAPI_NR_PARAM_TLV_MAX_PRACH_FD_OCCASIONS_IN_A_SLOT_TAG 0x0035 +#define NFAPI_NR_PARAM_TLV_RSSI_MEASUREMENT_SUPPORT_TAG 0x0036 + +typedef struct +{ + nfapi_uint16_tlv_t release_capability; //TAG 0x0001 + nfapi_uint16_tlv_t phy_state; + nfapi_uint8_tlv_t skip_blank_dl_config; + nfapi_uint8_tlv_t skip_blank_ul_config; + nfapi_uint16_tlv_t num_config_tlvs_to_report; + nfapi_uint8_tlv_t* config_tlvs_to_report_list; +} nfapi_nr_cell_param_t; + +//table 3-10 Carrier parameters +typedef struct +{ + nfapi_uint8_tlv_t cyclic_prefix;//TAG 0x0006 + nfapi_uint16_tlv_t supported_subcarrier_spacings_dl; + nfapi_uint16_tlv_t supported_bandwidth_dl; + nfapi_uint8_tlv_t supported_subcarrier_spacings_ul; + nfapi_uint16_tlv_t supported_bandwidth_ul; + +} nfapi_nr_carrier_param_t; + +//table 3-11 PDCCH parameters +typedef struct +{ + nfapi_uint8_tlv_t cce_mapping_type; + nfapi_uint8_tlv_t coreset_outside_first_3_of_ofdm_syms_of_slot; + nfapi_uint8_tlv_t coreset_precoder_granularity_coreset; + nfapi_uint8_tlv_t pdcch_mu_mimo; + nfapi_uint8_tlv_t pdcch_precoder_cycling; + nfapi_uint8_tlv_t max_pdcch_per_slot;//TAG 0x0010 + +} nfapi_nr_pdcch_param_t; + +//table 3-12 PUCCH parameters +typedef struct +{ + nfapi_uint8_tlv_t pucch_formats; + nfapi_uint8_tlv_t max_pucchs_per_slot; + +} nfapi_nr_pucch_param_t; + +//table 3-13 PDSCH parameters +typedef struct +{ + nfapi_uint8_tlv_t pdsch_mapping_type; + nfapi_uint8_tlv_t pdsch_allocation_types; + nfapi_uint8_tlv_t pdsch_vrb_to_prb_mapping; + nfapi_uint8_tlv_t pdsch_cbg; + nfapi_uint8_tlv_t pdsch_dmrs_config_types; + nfapi_uint8_tlv_t pdsch_dmrs_max_length; + nfapi_uint8_tlv_t pdsch_dmrs_additional_pos; + nfapi_uint8_tlv_t max_pdsch_tbs_per_slot; + nfapi_uint8_tlv_t max_number_mimo_layers_pdsch; + nfapi_uint8_tlv_t supported_max_modulation_order_dl; + nfapi_uint8_tlv_t max_mu_mimo_users_dl; + nfapi_uint8_tlv_t pdsch_data_in_dmrs_symbols; + nfapi_uint8_tlv_t premption_support;//TAG 0x001F + nfapi_uint8_tlv_t pdsch_non_slot_support; + +} nfapi_nr_pdsch_param_t; + +//table 3-14 +typedef struct +{ + nfapi_uint8_tlv_t uci_mux_ulsch_in_pusch; + nfapi_uint8_tlv_t uci_only_pusch; + nfapi_uint8_tlv_t pusch_frequency_hopping; + nfapi_uint8_tlv_t pusch_dmrs_config_types; + nfapi_uint8_tlv_t pusch_dmrs_max_len; + nfapi_uint8_tlv_t pusch_dmrs_additional_pos; + nfapi_uint8_tlv_t pusch_cbg; + nfapi_uint8_tlv_t pusch_mapping_type; + nfapi_uint8_tlv_t pusch_allocation_types; + nfapi_uint8_tlv_t pusch_vrb_to_prb_mapping; + nfapi_uint8_tlv_t pusch_max_ptrs_ports; + nfapi_uint8_tlv_t max_pduschs_tbs_per_slot; + nfapi_uint8_tlv_t max_number_mimo_layers_non_cb_pusch; + nfapi_uint8_tlv_t supported_modulation_order_ul; + nfapi_uint8_tlv_t max_mu_mimo_users_ul; + nfapi_uint8_tlv_t dfts_ofdm_support; + nfapi_uint8_tlv_t pusch_aggregation_factor;//TAG 0x0031 + +} nfapi_nr_pusch_param_t; + +//table 3-15 +typedef struct +{ + nfapi_uint8_tlv_t prach_long_formats; + nfapi_uint8_tlv_t prach_short_formats; + nfapi_uint8_tlv_t prach_restricted_sets; + nfapi_uint8_tlv_t max_prach_fd_occasions_in_a_slot; +} nfapi_nr_prach_param_t; + +//table 3-16 +typedef struct +{ + nfapi_uint8_tlv_t rssi_measurement_support; +} nfapi_nr_measurement_param_t; + +//-------------------------------------------// +//3.3.2 CONFIG + + +typedef enum { + NFAPI_NR_CONFIG_MSG_OK = 0, + NFAPI_NR_CONFIG_MSG_INVALID_CONFIG //The configuration provided has missing mandatory TLVs, or TLVs that are invalid or unsupported in this state. +} nfapi_nr_config_errors_e; + +/*typedef struct { + nfapi_nr_config_errors_e error_code; + uint8_t number_of_invalid_tlvs_that_can_only_be_configured_in_idle; + uint8_t unmber_of_missing_tlvs; + //? ↓ + nfapi_nr_config_tlv_t* tlv_invalid_list; + nfapi_nr_config_tlv_t* tlv_invalid_idle_list; + nfapi_nr_config_tlv_t* tlv_invalid_running_list; + nfapi_nr_config_tlv_t* tlv_missing_list; + +} nfapi_nr_config_response_t;*/ + +//nfapi_nr_config_tlv_format_t carrier config ~ precoding config: + +#define NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG 0x1001 +#define NFAPI_NR_CONFIG_DL_FREQUENCY_TAG 0x1002 +#define NFAPI_NR_CONFIG_DL_K0_TAG 0x1003 +#define NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG 0x1004 +#define NFAPI_NR_CONFIG_NUM_TX_ANT_TAG 0x1005 +#define NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG 0x1006 +#define NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG 0x1007 +#define NFAPI_NR_CONFIG_UL_K0_TAG 0x1008 +#define NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG 0x1009 +#define NFAPI_NR_CONFIG_NUM_RX_ANT_TAG 0x100A +#define NFAPI_NR_CONFIG_FREQUENCY_SHIFT_7P5KHZ_TAG 0x100B + +#define NFAPI_NR_CONFIG_PHY_CELL_ID_TAG 0x100C +#define NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG 0x100D + +#define NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG 0x100E +#define NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG 0x100F +#define NFAPI_NR_CONFIG_SCS_COMMON_TAG 0x1010 + +#define NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG 0x1011 +#define NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG 0x1012 +#define NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG 0x1013 +#define NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG 0x1014 +#define NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG 0x1015 +#define NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG 0x1016 +#define NFAPI_NR_CONFIG_K1_TAG 0x1017 +#define NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG 0x1018 +#define NFAPI_NR_CONFIG_NUM_UNUSED_ROOT_SEQUENCES_TAG 0x1019 +#define NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG 0x101A +#define NFAPI_NR_CONFIG_SSB_PER_RACH_TAG 0x101B +#define NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG 0x101C + +#define NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG 0x101D +#define NFAPI_NR_CONFIG_BETA_PSS_TAG 0x101E +#define NFAPI_NR_CONFIG_SSB_PERIOD_TAG 0x101F +#define NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG 0x1020 +#define NFAPI_NR_CONFIG_MIB_TAG 0x1021 +#define NFAPI_NR_CONFIG_SSB_MASK_TAG 0x1022 +#define NFAPI_NR_CONFIG_BEAM_ID_TAG 0x1023 +#define NFAPI_NR_CONFIG_SS_PBCH_MULTIPLE_CARRIERS_IN_A_BAND_TAG 0x1024 +#define NFAPI_NR_CONFIG_MULTIPLE_CELLS_SS_PBCH_IN_A_CARRIER_TAG 0x1025 +#define NFAPI_NR_CONFIG_TDD_PERIOD_TAG 0x1026 +#define NFAPI_NR_CONFIG_SLOT_CONFIG_TAG 0x1027 + +#define NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG 0x1028 + +//table 3-21 +typedef struct +{ + nfapi_uint16_tlv_t dl_bandwidth;//Carrier bandwidth for DL in MHz [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400 + nfapi_uint32_tlv_t dl_frequency; //Absolute frequency of DL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000 + nfapi_uint16_tlv_t dl_k0[5];//𝑘_{0}^{𝜇} for each of the numerologies [38.211, sec 5.3.1] Value: 0 ->23699 + nfapi_uint16_tlv_t dl_grid_size[5];//Grid size 𝑁_{𝑔𝑟𝑖𝑑}^{𝑠𝑖𝑧𝑒,𝜇} for each of the numerologies [38.211, sec 4.4.2] Value: 0->275 0 = this numerology not used + nfapi_uint16_tlv_t num_tx_ant;//Number of Tx antennas + nfapi_uint16_tlv_t uplink_bandwidth;//Carrier bandwidth for UL in MHz. [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400 + nfapi_uint32_tlv_t uplink_frequency;//Absolute frequency of UL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000 + nfapi_uint16_tlv_t ul_k0[5];//𝑘0 𝜇 for each of the numerologies [38.211, sec 5.3.1] Value: : 0 ->23699 + nfapi_uint16_tlv_t ul_grid_size[5];//Grid size 𝑁𝑔𝑟𝑖𝑑 𝑠𝑖𝑧𝑒,𝜇 for each of the numerologies [38.211, sec 4.4.2]. Value: 0->275 0 = this numerology not used + nfapi_uint16_tlv_t num_rx_ant;// + nfapi_uint8_tlv_t frequency_shift_7p5khz;//Indicates presence of 7.5KHz frequency shift. Value: 0 = false 1 = true + +} nfapi_nr_carrier_config_t; + +//table 3-22 +typedef struct +{ + nfapi_uint8_tlv_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007 + nfapi_uint8_tlv_t frame_duplex_type;//Frame duplex type Value: 0 = FDD 1 = TDD + +} nfapi_nr_cell_config_t; + +//table 3-23 +typedef struct +{ + nfapi_uint32_tlv_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm) + nfapi_uint8_tlv_t bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload + nfapi_uint8_tlv_t scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3 + +} nfapi_nr_ssb_config_t; + +//table 3-24 +/*typedef struct { + uint8_t unused_root_sequences;//Unused root sequence or sequences per FD occasion. Required for noise estimation. +} nfapi_nr_num_unused_root_sequences_t;*/ + +typedef struct +{ + uint8_t num_prach_fd_occasions; + nfapi_uint16_tlv_t prach_root_sequence_index;//Starting logical root sequence index, 𝑖, equivalent to higher layer parameter prach-RootSequenceIndex [38.211, sec 6.3.3.1] Value: 0 -> 837 + nfapi_uint8_tlv_t num_root_sequences;//Number of root sequences for a particular FD occasion that are required to generate the necessary number of preambles + nfapi_uint16_tlv_t k1;//Frequency offset (from UL bandwidth part) for each FD. [38.211, sec 6.3.3.2] Value: from 0 to 272 + nfapi_uint8_tlv_t prach_zero_corr_conf;//PRACH Zero CorrelationZone Config which is used to dervive 𝑁𝑐𝑠 [38.211, sec 6.3.3.1] Value: from 0 to 15 + nfapi_uint8_tlv_t num_unused_root_sequences;//Number of unused sequences available for noise estimation per FD occasion. At least one unused root sequence is required per FD occasion. + nfapi_uint8_tlv_t* unused_root_sequences_list;//Unused root sequence or sequences per FD occasion. Required for noise estimation. + +} nfapi_nr_num_prach_fd_occasions_t; + +typedef struct +{ + nfapi_uint8_tlv_t prach_sequence_length;//RACH sequence length. Only short sequence length is supported for FR2. [38.211, sec 6.3.3.1] Value: 0 = Long sequence 1 = Short sequence + nfapi_uint8_tlv_t prach_sub_c_spacing;//Subcarrier spacing of PRACH. [38.211 sec 4.2] Value:0->4 + nfapi_uint8_tlv_t restricted_set_config;//PRACH restricted set config Value: 0: unrestricted 1: restricted set type A 2: restricted set type B + nfapi_uint8_tlv_t num_prach_fd_occasions;//Corresponds to the parameter 𝑀 in [38.211, sec 6.3.3.2] which equals the higher layer parameter msg1FDM Value: 1,2,4,8 + nfapi_nr_num_prach_fd_occasions_t* num_prach_fd_occasions_list; + nfapi_uint8_tlv_t ssb_per_rach;//SSB-per-RACH-occasion Value: 0: 1/8 1:1/4, 2:1/2 3:1 4:2 5:4, 6:8 7:16 + nfapi_uint8_tlv_t prach_multiple_carriers_in_a_band;//0 = disabled 1 = enabled + +} nfapi_nr_prach_config_t; + +//table 3-25 +typedef struct +{ + nfapi_uint32_tlv_t ssb_mask;//Bitmap for actually transmitted SSB. MSB->LSB of first 32 bit number corresponds to SSB 0 to SSB 31 MSB->LSB of second 32 bit number corresponds to SSB 32 to SSB 63 Value for each bit: 0: not transmitted 1: transmitted + +} nfapi_nr_ssb_mask_size_2_t; + +typedef struct +{ + nfapi_uint8_tlv_t beam_id[64];//BeamID for each SSB in SsbMask. For example, if SSB mask bit 26 is set to 1, then BeamId[26] will be used to indicate beam ID of SSB 26. Value: from 0 to 63 + +} nfapi_nr_ssb_mask_size_64_t; + +typedef struct +{ + nfapi_uint16_tlv_t ssb_offset_point_a;//Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Given in PRB [38.211, section 4.4.4.2] Value: 0->2199 + nfapi_uint8_tlv_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block [38.213, sec 4.1] Values: 0 = 0dB + nfapi_uint8_tlv_t ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160 + nfapi_uint8_tlv_t ssb_subcarrier_offset;//ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (38.211, section 7.4.3.1) Value: 0->31 + nfapi_uint32_tlv_t MIB;//MIB payload, where the 24 MSB are used and represent the MIB in [38.331 MIB IE] and represent 0 1 2 3 1 , , , ,..., A− a a a a a [38.212, sec 7.1.1] + nfapi_nr_ssb_mask_size_2_t ssb_mask_list[2]; + nfapi_nr_ssb_mask_size_64_t* ssb_beam_id_list;//64 + nfapi_uint8_tlv_t ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled + nfapi_uint8_tlv_t multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled + +} nfapi_nr_ssb_table_t; + +//table 3-26 + +//? +typedef struct +{ + nfapi_uint8_tlv_t slot_config;//For each symbol in each slot a uint8_t value is provided indicating: 0: DL slot 1: UL slot 2: Guard slot + +} nfapi_nr_max_num_of_symbol_per_slot_t; + +typedef struct +{ + nfapi_nr_max_num_of_symbol_per_slot_t* max_num_of_symbol_per_slot_list; + +} nfapi_nr_max_tdd_periodicity_t; + +typedef struct +{ + nfapi_uint8_tlv_t tdd_period;//DL UL Transmission Periodicity. Value:0: ms0p5 1: ms0p625 2: ms1 3: ms1p25 4: ms2 5: ms2p5 6: ms5 7: ms10 8: ms3 9: ms4 + nfapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list; + +} nfapi_nr_tdd_table_t; + +//table 3-27 +typedef struct +{ + nfapi_uint8_tlv_t rssi_measurement;//RSSI measurement unit. See Table 3-16 for RSSI definition. Value: 0: Do not report RSSI 1: dBm 2: dBFS + +} nfapi_nr_measurement_config_t; + + +typedef struct { + uint8_t num_tlv; + nfapi_nr_carrier_config_t carrier_config; + nfapi_nr_cell_config_t cell_config; + nfapi_nr_ssb_config_t ssb_config; + nfapi_nr_prach_config_t prach_config; + nfapi_nr_ssb_table_t ssb_table; + nfapi_nr_tdd_table_t tdd_table; + nfapi_nr_measurement_config_t measurement_config; +} nfapi_nr_config_request_scf_t; + + +//------------------------------// +//3.3.3 START + +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_start_request_t; + +typedef enum { + NFAPI_NR_START_MSG_INVALID_STATE +} nfapi_nr_start_errors_e; + +//3.3.4 STOP + +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_stop_request_t; + +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_stop_indication_t; + +typedef enum { + NFAPI_NR_STOP_MSG_INVALID_STATE +} nfapi_nr_stop_errors_e; + +//3.3.5 PHY Notifications +typedef enum { + NFAPI_NR_PHY_API_MSG_OK =0x0, + NFAPI_NR_PHY_API_MSG_INVALID_STATE =0x1, + NFAPI_NR_PHY_API_MSG_INVALID_CONFIG =0x2, + NFAPI_NR_PHY_API_SFN_OUT_OF_SYNC =0X3, + NFAPI_NR_PHY_API_MSG_SLOR_ERR =0X4, + NFAPI_NR_PHY_API_MSG_BCH_MISSING =0X5, + NFAPI_NR_PHY_API_MSG_INVALID_SFN =0X6, + NFAPI_NR_PHY_API_MSG_UL_DCI_ERR =0X7, + NFAPI_NR_PHY_API_MSG_TX_ERR =0X8 +} nfapi_nr_phy_notifications_errors_e; + +typedef struct { + uint16_t sfn; //0~1023 + uint16_t slot;//0~319 + nfapi_nr_phy_msg_type_e msg_id;//Indicate which message received by the PHY has an error. Values taken from Table 3-4. + nfapi_nr_phy_notifications_errors_e error_code; +} nfapi_nr_phy_notifications_error_indicate_t; + +//-----------------------// +//3.3.6 Storing Precoding and Beamforming Tables + +//table 3-32 +//? +typedef struct { + uint16_t beam_idx; //0~65535 +} nfapi_nr_dig_beam_t; + +typedef struct { + uint16_t dig_beam_weight_Re; + uint16_t dig_beam_weight_Im; +} nfapi_nr_txru_t; + +typedef struct { + uint16_t num_dig_beams; //0~65535 + uint16_t num_txrus; //0~65535 + nfapi_nr_dig_beam_t* dig_beam_list; + nfapi_nr_txru_t* txru_list; +} nfapi_nr_dbt_pdu_t; + + +//table 3-33 +//? +typedef struct { + uint16_t num_ant_ports; + int16_t precoder_weight_Re; + int16_t precoder_weight_Im; +} nfapi_nr_num_ant_ports_t; + +typedef struct { + uint16_t numLayers; //0~65535 + nfapi_nr_num_ant_ports_t* num_ant_ports_list; +} nfapi_nr_num_layers_t; + +typedef struct { + uint16_t pm_idx; //0~65535 + nfapi_nr_num_layers_t* num_layers_list; //0~65535 + //nfapi_nr_num_ant_ports_t* num_ant_ports_list; +} nfapi_nr_pm_pdu_t; + + +// Section 3.4 + +// Section 3.4.1 slot indication +#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_0 1000 //us +#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_1 50 //us +#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_2 250 //us +#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_3 125 //us + +typedef struct { + uint16_t sfn; //0->1023 + uint16_t slot;//0->319 + +} nfapi_nr_slot_indication_t; + +// 3.4.2 + +//for pdcch_pdu: + +typedef struct +{ + uint16_t beam_idx;//Index of the digital beam weight vector pre-stored at cell configuration. The vector maps this input port to output TXRUs. Value: 0->65535 + +}nfapi_nr_dig_bf_interface_t; + +typedef struct +{ + uint16_t pm_idx;//Index to precoding matrix (PM) pre-stored at cell configuration. Note: If precoding is not used this parameter should be set to 0. Value: 0->65535. + nfapi_nr_dig_bf_interface_t* dig_bf_interface_list; + +}nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t; + +/* +//table 3-43 +typedef struct +{ + uint16_t num_prgs;//Number of PRGs spanning this allocation. Value : 1->275 + uint16_t prg_size;//Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275 + //watchout: dig_bf_interfaces here, in table 3-53 it's dig_bf_interface + uint8_t dig_bf_interfaces;//Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255 + nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t* prgs_list;// + +}nfapi_nr_tx_precoding_and_beamforming_t; +*/ + +typedef struct { + /// Number of PRGs spanning this allocation. Value : 1->275 + uint16_t numPRGs; + /// Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275 + uint16_t prgSize; + /// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255 + uint8_t digBFInterfaces; + uint16_t PMIdx[275]; + uint16_t *beamIdx[275]; +} nfapi_nr_tx_precoding_and_beamforming_t; + +//table 3-37 + +#define DCI_PAYLOAD_BTYE_LEN 12 //? TS38.212 sec 7.3.1 + +typedef struct +{ + uint16_t rnti;// + uint16_t scrambling_id;// + uint16_t scrambling_rnti;/* */ + uint8_t cce_index;// + uint8_t aggregation_level;// + nfapi_nr_tx_precoding_and_beamforming_t* precoding_and_beamforming_list; + //tx power info + uint8_t beta_pdcch_1_0;/*PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. This is ratio of +SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 */ + uint8_t power_control_offset_ss;//PDCCH power value used for all other PDCCH Formats. This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB + uint16_t payload_size_bits;//The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0-> DCI_PAYLOAD_BTYE_LEN*8 + uint8_t payload[DCI_PAYLOAD_BTYE_LEN];//DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB + +} nfapi_nr_dl_dci_pdu_t; + +typedef struct { + /// Number of PRGs spanning this allocation. Value : 1->275 + uint16_t numPRGs; + /// Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275 + uint16_t prgSize; + /// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255 + uint8_t digBFInterfaces; + uint16_t PMIdx[275]; + uint16_t *beamIdx[275]; +} nr_beamforming_t; + +#define MAX_DCI_CORESET 8 +#define DCI_PAYLOAD_BYTE_LEN 8 + +typedef struct { + ///Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP,Value: 1->275 + uint16_t BWPSize; + ///bandwidth part start RB index from reference CRB, [TS38.213 sec 12], Value: 0->274 + uint16_t BWPStart; + ///subcarrierSpacing [TS38.211 sec 4.2], Value:0->4 + uint8_t SubcarrierSpacing; + ///Cyclic prefix type [TS38.211 sec 4.2], 0: Normal; 1: Extended + uint8_t CyclicPrefix; + ///Starting OFDM symbol for the CORESET, Value: 0->13 + uint8_t StartSymbolIndex; +///Contiguous time duration of the CORESET in number of symbols. Corresponds to L1 parameter 𝑁𝑠𝑦𝑚𝑏_𝐶𝑂𝑅𝐸𝑆𝐸𝑇 [TS38.211 sec 7.3.2.2] Value: 1,2,3 + uint8_t DurationSymbols; + ///Frequency domain resources. This is a bitmap defining non-overlapping groups of 6 PRBs in ascending order. [TS38.213 10.1]. Also, corresponds to L1 parameter CORE SET RB N [TS38.211 sec 7.3.2.2] Bitmap of uint8 array. 45 bits. + uint8_t FreqDomainResource[6]; + ///CORESET-CCE-to-REG-mapping-type [TS38.211 sec 7.3.2.2] 0: non-interleaved 1: interleaved + uint8_t CceRegMappingType; + ///The number of REGs in a bundle. Must be 6 for cceRegMappingType = nonInterleaved. For cceRegMappingType = interleaved, must belong to {2,6} if duration = 1,2 and must belong to {3,6} if duration = 3. Corresponds to parameter L. [TS38.211 sec 7.3.2.2] Value: 2,3,6 + uint8_t RegBundleSize; + ///The interleaver size. For interleaved mapping belongs to {2,3,6} and for non-interleaved mapping is NA. Corresponds to parameter R. [TS38.211 sec 7.3.2.2] Value: 2,3,6 CoreSetType + uint8_t InterleaverSize; + ///[TS38.211 sec 7.3.2.2 and sec 7.4.1.3.2] 0: CORESET is configured by the PBCH or SIB1 (subcarrier 0 of CRB0 for DMRS mapping) 1: otherwise (subcarrier 0 of CORESET) + uint8_t CoreSetType; + ///[TS38.211 sec 7.3.2.2] Not applicable for non-interleaved mapping. For interleaved mapping and a PDCCH transmitted in a CORESET configured by the PBCH or SIB1 this should be set to phy cell ID. Value: 10 bits Otherwise, for interleaved mapping this is set to 0-> max num of PRBs. Value 0-> 275 + uint16_t ShiftIndex; + ///Granularity of precoding [TS38.211 sec 7.3.2.2] Field Type Description 0: sameAsRegBundle 1: allContiguousRBs + uint8_t precoderGranularity; + ///Number of DCIs in this CORESET.Value: 0->MaxDciPerSlot + uint16_t numDlDci; + ///The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535. + uint16_t RNTI[MAX_DCI_CORESET]; + ///For a UE-specific search space it equals the higher-layer parameter PDCCH-DMRSScrambling-ID if configured, otherwise it should be set to the phy cell ID. [TS38.211, sec 7.3.2.3] Value: 0->65535 + uint16_t ScramblingId[MAX_DCI_CORESET]; + ///For a UE-specific search space where PDCCH-DMRSScrambling- ID is configured This param equals the CRNTI. Otherwise, it should be set to 0. [TS38.211, sec 7.3.2.3] Value: 0 -> 65535 + uint16_t ScramblingRNTI[MAX_DCI_CORESET]; + ///CCE start Index used to send the DCI Value: 0->135 + uint8_t CceIndex[MAX_DCI_CORESET]; + ///Aggregation level used [TS38.211, sec 7.3.2.1] Value: 1,2,4,8,16 + uint8_t AggregationLevel[MAX_DCI_CORESET]; + ///Precoding and Beamforming structure See Table 3-43 + nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming[MAX_DCI_CORESET]; + ///PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. This is ratio of SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 Report title: 5G FAPI: PHY API Specification Issue date: 29 June 2019 Version: 222.10.17 68 Field Type Description representing -8 to 8 dB in 1dB steps + uint8_t beta_PDCCH_1_0[MAX_DCI_CORESET]; + ///PDCCH power value used for all other PDCCH Formats. This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB,1: 0dB,2: 3dB,3: 6dB + uint8_t powerControlOffsetSS[MAX_DCI_CORESET]; +///The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BTYE_LEN*8 + uint16_t PayloadSizeBits[MAX_DCI_CORESET]; + ///DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB + uint8_t Payload[MAX_DCI_CORESET][DCI_PAYLOAD_BYTE_LEN]; +} nfapi_nr_dl_tti_pdcch_pdu_rel15_t; + +typedef struct { + uint16_t pduBitmap; + uint16_t rnti; + uint16_t pduIndex; + // BWP [TS38.213 sec 12] + /// Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP, Value: 1->275 + uint16_t BWPSize; + /// bandwidth part start RB index from reference CRB [TS38.213 sec 12],Value: 0->274 + uint16_t BWPStart; + /// subcarrierSpacing [TS38.211 sec 4.2], Value:0->4 + uint8_t SubcarrierSpacing; + /// Cyclic prefix type [TS38.211 sec 4.2], 0: Normal; 1: Extended + uint8_t CyclicPrefix; + // Codeword information + /// Number of code words for this RNTI (UE), Value: 1 -> 2 + uint8_t NrOfCodewords; + /// Target coding rate [TS38.212 sec 5.4.2.1 and 38.214 sec 5.1.3.1]. This is the number of information bits per 1024 coded bits expressed in 0.1 bit units + uint16_t targetCodeRate[2]; + /// QAM modulation [TS38.212 sec 5.4.2.1 and 38.214 sec 5.1.3.1], Value: 2,4,6,8 + uint8_t qamModOrder[2]; + /// MCS index [TS38.214, sec 5.1.3.1], should match value sent in DCI Value : 0->31 + uint8_t mcsIndex[2]; + /// MCS-Table-PDSCH [TS38.214, sec 5.1.3.1] 0: notqam256, 1: qam256, 2: qam64LowSE + uint8_t mcsTable[2]; + /// Redundancy version index [TS38.212, Table 5.4.2.1-2 and 38.214, Table 5.1.2.1-2], should match value sent in DCI Value : 0->3 + uint8_t rvIndex[2]; + /// Transmit block size (in bytes) [TS38.214 sec 5.1.3.2], Value: 0->65535 + uint32_t TBSize[2]; + /// dataScramblingIdentityPdsch [TS38.211, sec 7.3.1.1], It equals the higher-layer parameter Datascrambling-Identity if configured and the RNTI equals the C-RNTI, otherwise L2 needs to set it to physical cell id. Value: 0->65535 + uint16_t dataScramblingId; + /// Number of layers [TS38.211, sec 7.3.1.3]. Value : 1->8 + uint8_t nrOfLayers; + /// PDSCH transmission schemes [TS38.214, sec5.1.1] 0: Up to 8 transmission layers + uint8_t transmissionScheme; + /// Reference point for PDSCH DMRS "k" - used for tone mapping [TS38.211, sec 7.4.1.1.2] Resource block bundles [TS38.211, sec 7.3.1.6] Value: 0 -> 1 If 0, the 0 reference point for PDSCH DMRS is at Point A [TS38.211 sec 4.4.4.2]. Resource block bundles generated per sub-bullets 2 and 3 in [TS38.211, sec 7.3.1.6]. For sub-bullet 2, the start of bandwidth part must be set to the start of actual bandwidth part +NstartCORESET and the bandwidth of the bandwidth part must be set to the bandwidth of the initial bandwidth part. If 1, the DMRS reference point is at the lowest VRB/PRB of the allocation. Resource block bundles generated per sub-bullets 1 [TS38.211, sec 7.3.1.6] + uint8_t refPoint; + // DMRS [TS38.211 sec 7.4.1.1] + /// DMRS symbol positions [TS38.211, sec 7.4.1.1.2 and Tables 7.4.1.1.2-3 and 7.4.1.1.2-4] Bitmap occupying the 14 LSBs with: bit 0: first symbol and for each bit 0: no DMRS 1: DMRS + uint16_t dlDmrsSymbPos; + /// DL DMRS config type [TS38.211, sec 7.4.1.1.2] 0: type 1, 1: type 2 + uint8_t dmrsConfigType; + /// DL-DMRS-Scrambling-ID [TS38.211, sec 7.4.1.1.2 ] If provided by the higher-layer and the PDSCH is scheduled by PDCCH with CRC scrambled by CRNTI or CS-RNTI, otherwise, L2 should set this to physical cell id. Value: 0->65535 + uint16_t dlDmrsScramblingId; + /// DMRS sequence initialization [TS38.211, sec 7.4.1.1.2]. Should match what is sent in DCI 1_1, otherwise set to 0. Value : 0->1 + uint8_t SCID; + /// Number of DM-RS CDM groups without data [TS38.212 sec 7.3.1.2.2] [TS38.214 Table 4.1-1] it determines the ratio of PDSCH EPRE to DM-RS EPRE. Value: 1->3 + uint8_t numDmrsCdmGrpsNoData; + /// DMRS ports. [TS38.212 7.3.1.2.2] provides description between DCI 1-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used + uint16_t dmrsPorts; + // Pdsch Allocation in frequency domain [TS38.214, sec 5.1.2.2] + /// Resource Allocation Type [TS38.214, sec 5.1.2.2] 0: Type 0, 1: Type 1 + uint8_t resourceAlloc; + /// For resource alloc type 0. TS 38.212 V15.0.x, 7.3.1.2.2 bitmap of RBs, 273 rounded up to multiple of 32. This bitmap is in units of VRBs. LSB of byte 0 of the bitmap represents the first RB of the bwp + uint8_t rbBitmap[36]; + /// For resource allocation type 1. [TS38.214, sec 5.1.2.2.2] The starting resource block within the BWP for this PDSCH. Value: 0->274 + uint16_t rbStart; + /// For resource allocation type 1. [TS38.214, sec 5.1.2.2.2] The number of resource block within for this PDSCH. Value: 1->275 + uint16_t rbSize; + /// VRB-to-PRB-mapping [TS38.211, sec 7.3.1.6] 0: non-interleaved 1: interleaved with RB size 2 2: Interleaved with RB size 4 + uint8_t VRBtoPRBMapping; + // Resource Allocation in time domain [TS38.214, sec 5.1.2.1] + /// Start symbol index of PDSCH mapping from the start of the slot, S. [TS38.214, Table 5.1.2.1-1] Value: 0->13 + uint8_t StartSymbolIndex; + /// PDSCH duration in symbols, L [TS38.214, Table 5.1.2.1-1] Value: 1->14 + uint8_t NrOfSymbols; + // PTRS [TS38.214, sec 5.1.6.3] + /// PT-RS antenna ports [TS38.214, sec 5.1.6.3] [TS38.211, table 7.4.1.2.2-1] Bitmap occupying the 6 LSBs with: bit 0: antenna port 1000 bit 5: antenna port 1005 and for each bit 0: PTRS port not used 1: PTRS port used + uint8_t PTRSPortIndex ; + /// PT-RS time density [TS38.214, table 5.1.6.3-1] 0: 1 1: 2 2: 4 + uint8_t PTRSTimeDensity; + /// PT-RS frequency density [TS38.214, table 5.1.6.3-2] 0: 2 1: 4 + uint8_t PTRSFreqDensity; + /// PT-RS resource element offset [TS38.211, table 7.4.1.2.2-1] Value: 0->3 + uint8_t PTRSReOffset; + /// PT-RS-to-PDSCH EPRE ratio [TS38.214, table 4.1-2] Value :0->3 + uint8_t nEpreRatioOfPDSCHToPTRS; + // Beamforming + nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming; +}nfapi_nr_dl_tti_pdsch_pdu_rel15_t; + + +//for pdsch_pdu: +/* +typedef struct +{ + uint16_t target_code_rate;// + uint8_t qam_mod_order;// + uint8_t mcs_index;// + uint8_t mcs_table;// + uint8_t rv_index;// + uint32_t tb_size;// +} nfapi_nr_code_word_t; + +//table 3-38 +typedef struct +{ + uint16_t pdu_bit_map;//Bitmap indicating presence of optional PDUs Bit 0: pdschPtrs - Indicates PTRS included (FR2) Bit 1:cbgRetxCtrl (Present when CBG based retransmit is used) All other bits reserved + uint16_t rnti;//The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535 + uint16_t pdu_index;// + uint16_t bwp_size;//Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP Value: 1->275 + uint16_t bwp_start;//bandwidth part start RB index from reference CRB [TS38.213 sec 12] Value: 0->274 + uint8_t subcarrier_spacing;//Value:0->4 + uint8_t cyclic_prefix;//0: Normal; 1: Extended + uint8_t nr_of_code_words;//Number of code words for this RNTI (UE) Value: 1 -> 2 + nfapi_nr_code_word_t* code_word_list; + uint16_t data_scrambling_id;// + uint8_t nr_of_layers;// + uint8_t transmission_scheme;//PDSCH transmission schemes [TS38.214, sec 5.1.1] 0: Up to 8 transmission layers + uint8_t ref_point;//Reference point for PDSCH DMRS "k" - used for tone mapping + //DMRS + uint16_t dl_dmrs_symb_pos;//Bitmap occupying the 14 LSBs with: bit 0: first symbol and for each bit 0: no DMRS 1: DMRS + uint8_t dmrs_config_type;//DL DMRS config type[TS38.211, sec 7.4.1.1.2] 0: type 1 1: type 2 + uint16_t dl_dmrs_scrambling_id;//DL-DMRS-Scrambling-ID [TS38.211, sec 7.4.1.1.2 ] If provided by the higher-layer and the PDSCH is scheduled by PDCCH with CRC scrambled by CRNTI or CS-RNTI, otherwise, L2 should set this to physical cell id. Value: 0->65535 + uint8_t scid;// 0 1 + uint8_t num_dmrs_cdm_grps_no_data;//Number of DM-RS CDM groups without data [TS38.212 sec 7.3.1.2.2] [TS38.214 Table 4.1-1] it determines the ratio of PDSCH EPRE to DM-RS EPRE. Value: 1->3 + uint16_t dmrs_ports;//DMRS ports. [TS38.212 7.3.1.2.2] provides description between DCI 1-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used + + //Pdsch Allocation in frequency domain [TS38.214, sec 5.1.2.2] + uint8_t resource_alloc;//Resource Allocation Type [TS38.214, sec 5.1.2.2] 0: Type 0 1: Type 1 + uint8_t rb_bit_map[36];//For resource alloc type 0. TS 38.212 V15.0.x, 7.3.1.2.2 bitmap of RBs, 273 rounded up to multiple of 32. This bitmap is in units of VRBs. LSB of byte 0 of the bitmap represents the first RB of the bwp + uint16_t rb_start;//For resource allocation type 1. [TS38.214, sec5.1.2.2.2] The starting resource block within the BWP for this PDSCH. Value: 0->274 + uint16_t rb_size;//For resource allocation type 1. [TS38.214, sec 5.1.2.2.2] The number of resource block within for this PDSCH. Value: 1->275 + uint8_t vrb_to_prb_mapping;//VRB-to-PRB-mapping [TS38.211, sec 7.3.1.6] 0: non-interleaved 1: interleaved with RB size 2 2: Interleaved with RB size 4 + //Resource Allocation in time domain [TS38.214, sec 5.1.2.1] + uint8_t start_symbol_index;//Start symbol index of PDSCH mapping from the start of the slot, S. [TS38.214, Table 5.1.2.1-1] Value: 0->13 + uint8_t nr_of_symbols;//PDSCH duration in symbols, L [TS38.214, Table 5.1.2.1-1] Value: 1->14 + //PTRS TS38.214 sec 5.1.6.3 + uint8_t ptrs_port_index;//PT-RS antenna ports [TS38.214, sec 5.1.6.3] [TS38.211, table 7.4.1.2.2-1] Bitmap occupying the 6 LSBs with: bit 0: ntenna port 1000 bit 5: antenna port 1005 and for each bit 0: PTRS port not used 1: PTRS port used + uint8_t ptrs_time_density;//PT-RS time density [TS38.214, table 5.1.6.3-1] 0: 1 1: 2 2: 4 + uint8_t ptrs_freq_density;//PT-RS frequency density [TS38.214, table[5.1.6.3-2] 0: 2 1: 4 + uint8_t ptrs_re_offset;//PT-RS resource element offset [TS38.211, table [7.4.1.2.2-1] + uint8_t n_epre_ratio_of_pdsch_to_ptrs;//PT-RS-to-PDSCH EPRE ratio [TS38.214, table 4.1-2] Value :0->3 + nfapi_nr_tx_precoding_and_beamforming_t* precoding_and_beamforming_list; + //TX power info + uint8_t power_control_offset;//Ratio of PDSCH EPRE to NZP CSI-RSEPRE [TS38.214, sec 5.2.2.3.1] Value :0->23 representing -8 to 15 dB in 1dB steps + uint8_t power_control_offset_ss;//Ratio of SSB/PBCH block EPRE to NZP CSI-RS EPRES [TS38.214, sec 5.2.2.3.1] Values: 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB + //CBG fields + uint8_t is_last_cb_present;//Indicates whether last CB is present in the CBG retransmission 0: CBG retransmission does not include last CB 1: CBG retransmission includes last CB If CBG Re-Tx includes last CB, L1 will add the TB CRC to the last CB in the payload before it is read into the LDPC HW unit + uint8_t is_inline_tb_crc;//Indicates whether TB CRC is part of data payload or control message 0: TB CRC is part of data payload 1: TB CRC is part of control message + uint32_t dl_tb_crc;//TB CRC: to be used in the last CB, applicable only if last CB is present + +} nfapi_nr_dlsch_pdu_t; +*/ + +//for csi-rs_pdu: + +//table 3-39 +typedef struct +{ + uint16_t bwp_size;// + uint16_t bwp_start;// + uint8_t subcarrier_spacing;// + uint8_t cyclic_prefix;// + uint16_t start_rb; + uint16_t nr_of_rbs; + uint8_t csi_type;//Value: 0:TRS 1:CSI-RS NZP 2:CSI-RS ZP + uint8_t row;//Row entry into the CSI Resource location table. [TS38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1] Value: 1-18 + uint16_t freq_domain;//Value: Up to the 12 LSBs, actual size is determined by the Row parameter + uint8_t symb_l0;//The time domain location l0 and firstOFDMSymbolInTimeDomain Value: 0->13 + uint8_t symb_l1;// + uint8_t cdm_type; + uint8_t freq_density;//The density field, p and comb offset (for dot5).0: dot5 (even RB), 1: dot5 (odd RB), 2: one, 3: three + uint16_t scramb_id;//ScramblingID of the CSI-RS [TS38.214, sec 5.2.2.3.1] Value: 0->1023 + //tx power info + uint8_t power_control_offset;//Ratio of PDSCH EPRE to NZP CSI-RSEPRE Value :0->23 representing -8 to 15 dB in 1dB steps + uint8_t power_control_offset_ss;//Ratio of SSB/PBCH block EPRE to NZP CSI-RS EPRES 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB + +} nfapi_nr_dl_tti_csi_rs_pdu_rel15_t; + +//for ssb_pdu: + +typedef struct +{ + uint32_t bch_payload;//BCH payload. The valid bits are indicated in the PARAM/CONFIG TLVs. If PARAM/CONFIG TLVs indicate MAC generates full bchPayload then the payload length is 31 bits with the 8 LSB bits being. Otherwise timing PBCH bits are generated by the PHY. And for bchPayload the 24 LSB are used. + +} nfapi_nr_mac_generated_mib_pdu_t; + +typedef struct +{ + uint8_t dmrs_type_a_position;//The position of the first DM-RS for downlink and uplink. + uint8_t pdcch_config_sib1;//The parameter PDCCH-ConfigSIB1 that determines a common ControlResourceSet (CORESET) a common search space and necessary PDCCH parameters. + uint8_t cell_barred;//The flag to indicate whether the cell is barred + uint8_t intra_freq_reselection;//The flag to controls cell selection/reselection to intrafrequency cells when the highest ranked cell is barred, or treated as barred by the UE. value 0 1 + +} nfapi_nr_phy_generated_mib_pdu_t; + + +typedef struct +{ + nfapi_nr_mac_generated_mib_pdu_t* mac_generated_mib_pdu; + nfapi_nr_phy_generated_mib_pdu_t* phy_generated_mib_pdu; + +} nfapi_nr_bch_payload_t; + +typedef struct { + /// Physical Cell ID Value 0~>1007 + uint16_t PhysCellId; + ///PSS EPRE to SSS EPRE in a SS/PBCH block 0 = 0dB 1 = 3dB + uint8_t BetaPss; + ///SS/PBCH block index within a SSB burst set. Required for PBCH DMRS scrambling. Value: 0->63 (Lmax) + uint8_t SsbBlockIndex; + /// ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (TS38.211, section 7.4.3.1) Value: 0->31 + uint8_t SsbSubcarrierOffset; + ///Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Value: 0->2199 + uint16_t ssbOffsetPointA; + /// A value indicating how the BCH payload is generated. This should match the PARAM/CONFIG TLVs. Value: 0: MAC generates the full PBCH payload, see Table 3-41, where bchPayload has 31 bits 1: PHY generates the timing PBCH bits, see Table 3-41, where the bchPayload has 24 bits 2: PHY generates the full PBCH payload + uint8_t bchPayloadFlag; + uint32_t bchPayload; + nfapi_nr_tx_precoding_and_beamforming_t precoding_and_beamforming; +} nfapi_nr_dl_tti_ssb_pdu_rel15_t; + +typedef struct { + nfapi_nr_dl_tti_ssb_pdu_rel15_t ssb_pdu_rel15; +} nfapi_nr_dl_tti_ssb_pdu; + +typedef struct { + nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_rs_pdu_rel15; +} nfapi_nr_dl_tti_csi_rs_pdu; + +typedef struct { + nfapi_nr_dl_tti_pdsch_pdu_rel15_t pdsch_pdu_rel15; +} nfapi_nr_dl_tti_pdsch_pdu; + +typedef struct { + nfapi_nr_dl_tti_pdcch_pdu_rel15_t pdcch_pdu_rel15; +} nfapi_nr_dl_tti_pdcch_pdu; + +typedef struct { + uint16_t PDUType; + uint16_t PDUSize; + + union { + nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu; + nfapi_nr_dl_tti_pdsch_pdu pdsch_pdu; + nfapi_nr_dl_tti_csi_rs_pdu csi_rs_pdu; + nfapi_nr_dl_tti_ssb_pdu ssb_pdu; + }; +} nfapi_nr_dl_tti_request_pdu_t; + +#define NFAPI_NR_MAX_DL_TTI_PDUS 32 +typedef struct { + /// Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255 + uint8_t nPDUs; + /// Number of UEs in the Group included in this message. Value 0 -> 255 + uint8_t nGroup; + /// List containing PDUs + nfapi_nr_dl_tti_request_pdu_t dl_tti_pdu_list[NFAPI_NR_MAX_DL_TTI_PDUS]; + /// Number of UE in this group. For SU-MIMO, one group includes one UE only. For MU-MIMO, one group includes up to 12 UEs. Value 1 -> 12 + uint8_t nUe[256]; + /// This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 255 + uint8_t PduIdx[256][12]; +} nfapi_nr_dl_tti_request_body_t; + +typedef struct { + nfapi_p7_message_header_t header; + /// System Frame Number (0-1023) + uint16_t SFN; + /// Slot number (0-319) + uint16_t Slot; + nfapi_nr_dl_tti_request_body_t dl_tti_request_body; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_dl_tti_request_t; + +/* +typedef struct +{ + nfapi_nr_dl_tti_pdcch_pdu* pdcch_pdu; + nfapi_nr_dl_tti_pdsch_pdu* pdsch_pdu; + nfapi_nr_dl_tti_csi_rs_pdu_t* csi_rs_pdu; + nfapi_nr_dl_tti_ssb_pdu_t* ssb_pdu; +} nfapi_nr_dl_pdu_configuration_t; +*/ + /* +typedef struct +{ + uint16_t pdu_type;//0: PDCCH PDU 1: PDSCH PDU 2: CSI-RS PDU 3: SSB PDU, + uint16_t pdu_size;//Size of the PDU control information (in bytes). This length value includes the 4 bytes required for the PDU type and PDU size parameters. Value 0 -> 65535 + nfapi_nr_dl_pdu_configuration_t* dl_pdu_configuration; + +} nfapi_nr_dl_tti_request_number_of_pdus_t; + + +typedef struct +{ + uint8_t pdu_idx;//This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 255 + +} nfapi_nr_dl_tti_request_number_of_ue_t; + +typedef struct +{ + uint8_t n_ue;//Number of UE in this group For SU-MIMO, one group includes one UE only. For MU-MIMO, one group includes up to 12 UEs. Value 1 -> 12 + nfapi_nr_dl_tti_request_number_of_ue_t* ue_list; + +} nfapi_nr_dl_tti_request_number_of_groups_t; + +//3.4.2 dl_tti_request +typedef struct { + uint16_t sfn; //0->1023 + uint16_t slot;//0->319 + uint8_t n_pdus;//Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255 + uint8_t n_group;//Number of UE Groups included in this message. Value 0 -> 255 + nfapi_nr_dl_tti_request_number_of_pdus_t* pdus_list; + nfapi_nr_dl_tti_request_number_of_groups_t* groups_list; + +} nfapi_nr_dl_tti_request_t; +*/ + +// Section 3.4.3 ul_tti_request + +//for prach_pdu: +typedef struct +{ + nfapi_nr_dig_bf_interface_t* dig_bf_interface_list; + +} nfapi_nr_ul_beamforming_number_of_prgs_t; + +typedef struct +{ + uint16_t num_prgs; + uint16_t prg_size; + //watchout: dig_bf_interface here, in table 3-43 it's dig_bf_interfaces + uint8_t dig_bf_interface; + nfapi_nr_ul_beamforming_number_of_prgs_t* prgs_list;// + +} nfapi_nr_ul_beamforming_t; + +typedef struct +{ + uint16_t phys_cell_id; + uint8_t num_prach_ocas; + uint8_t prach_format; + uint8_t num_ra; + uint8_t prach_start_symbol; + uint16_t num_cs;// + nfapi_nr_ul_beamforming_t beamforming; + +} nfapi_nr_prach_pdu_t; + +//for pusch_pdu: + + //for nfapi_nr_pusch_data_t; +typedef struct +{ + uint8_t rv_index; + uint8_t harq_process_id; + uint8_t new_data_indicator; + uint32_t tb_size; + uint16_t num_cb; + uint8_t cb_present_and_position[(NFAPI_MAX_NUM_CB+7) / 8]; + +} nfapi_nr_pusch_data_t; + //for nfapi_nr_pusch_uci_t +typedef struct +{ + uint16_t harq_ack_bit_length; + uint16_t csi_part1_bit_length; + uint16_t csi_part2_bit_length; + uint8_t alpha_scaling; + uint8_t beta_offset_harq_ack; + uint8_t beta_offset_csi1; + uint8_t beta_offset_csi2; + +} nfapi_nr_pusch_uci_t; + + //for nfapi_nr_pusch_ptrs_t +typedef struct +{ + uint16_t ptrs_port_index;//PT-RS antenna ports [TS38.214, sec6.2.3.1 and 38.212, section 7.3.1.1.2] Bitmap occupying the 12 LSBs with: bit 0: antenna port 0 bit 11: antenna port 11 and for each bit 0: PTRS port not used 1: PTRS port used + uint8_t ptrs_dmrs_port;//DMRS port corresponding to PTRS. + uint8_t ptrs_re_offset;//PT-RS resource element offset value taken from 0~11 +} nfapi_nr_ptrs_ports_t; + +typedef struct +{ + uint8_t num_ptrs_ports; + nfapi_nr_ptrs_ports_t* ptrs_ports_list; + uint8_t ptrs_time_density; + uint8_t ptrs_freq_density; + uint8_t ul_ptrs_power; + +}nfapi_nr_pusch_ptrs_t; + + //for nfapi_nr_dfts_ofdm_t +typedef struct +{ + uint8_t low_papr_group_number;//Group number for Low PAPR sequence generation. + uint16_t low_papr_sequence_number;//[TS38.211, sec 5.2.2] For DFT-S-OFDM. + uint8_t ul_ptrs_sample_density;//Number of PTRS groups [But I suppose this sentence is misplaced, so as the next one. --Chenyu] + uint8_t ul_ptrs_time_density_transform_precoding;//Number of samples per PTRS group + +} nfapi_nr_dfts_ofdm_t; + +#define PUSCH_PDU_BITMAP_PUSCH_DATA 0x1 +#define PUSCH_PDU_BITMAP_PUSCH_UCI 0x2 +#define PUSCH_PDU_BITMAP_PUSCH_PTRS 0x4 +#define PUSCH_PDU_BITMAP_DFTS_OFDM 0x8 + +typedef struct +{ + uint16_t pdu_bit_map;//Bitmap indicating presence of optional PDUs (see above) + uint16_t rnti; + uint32_t handle;//An opaque handling returned in the RxData.indication and/or UCI.indication message + //BWP + uint16_t bwp_size; + uint16_t bwp_start; + uint8_t subcarrier_spacing; + uint8_t cyclic_prefix; + //pusch information always include + uint16_t target_code_rate; + uint8_t qam_mod_order; + uint8_t mcs_index; + uint8_t mcs_table; + uint8_t transform_precoding; + uint16_t data_scrambling_id; + uint8_t nrOfLayers; + //DMRS + uint8_t ul_dmrs_symb_pos; + uint8_t dmrs_config_type; + uint16_t ul_dmrs_scrambling_id; + uint8_t scid;// + uint8_t num_dmrs_cdm_grps_no_data; + uint16_t dmrs_ports;//DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used + //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] + uint8_t resource_alloc; + uint8_t rb_bitmap[36];// + uint16_t rb_start; + uint16_t rb_size; + uint8_t vrb_to_prb_mapping; + uint8_t frequency_hopping; + uint16_t tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] + uint8_t uplink_frequency_shift_7p5khz; + //Resource Allocation in time domain + uint8_t start_symbol_index; + uint8_t nr_of_symbols; + //Optional Data only included if indicated in pduBitmap + nfapi_nr_pusch_data_t pusch_data; + nfapi_nr_pusch_uci_t pusch_uci; + nfapi_nr_pusch_ptrs_t pusch_ptrs; + nfapi_nr_dfts_ofdm_t dfts_ofdm; + //beamforming + nfapi_nr_ul_beamforming_t beamforming; + +} nfapi_nr_pusch_pdu_t; + +//for pucch_pdu: +typedef struct +{ + uint16_t rnti; + uint32_t handle; + //BWP + uint16_t bwp_size; + uint16_t bwp_start; + uint8_t subcarrier_spacing; + uint8_t cyclic_prefix; + + uint8_t format_type; + uint8_t multi_slot_tx_indicator; + uint8_t pi_2bpsk; + //pucch allocation in freq domain + uint16_t prb_start; + uint16_t prb_size; + //pucch allocation in tome domain + uint8_t start_symbol_index; + uint8_t nr_of_symbols; + //hopping info + uint8_t freq_hop_flag; + uint16_t second_hop_prb; + uint8_t group_hop_flag; + uint8_t sequence_hop_flag; + uint16_t hopping_id; + uint16_t initial_cyclic_shift; + + uint16_t data_scrambling_id; + uint8_t time_domain_occ_idx; + uint8_t pre_dft_occ_idx; + uint8_t pre_dft_occ_len; + //DMRS + uint8_t add_dmrs_flag; + uint16_t dmrs_scrambling_id; + uint8_t dmrs_cyclic_shift; + + uint8_t sr_flag; + uint8_t bit_len_harq; + uint16_t bit_len_csi_part1; + uint16_t bit_len_csi_part2; + + nfapi_nr_ul_beamforming_t beamforming; + +} nfapi_nr_pucch_pdu_t; + +//for srs_pdu: + +typedef struct +{ + uint16_t rnti;//UE RNTI + uint32_t handle;//An opaque handling returned in the SRS.indication + //BWP + uint16_t bwp_size; + uint16_t bwp_start; + uint8_t subcarrier_spacing; + uint8_t cyclic_prefix; + + uint8_t num_ant_ports; + uint8_t num_symbols; + uint8_t num_repetitions; + uint8_t time_start_position;//Starting position in the time domain l0; Note: the MAC undertakes the translation from startPosition to 𝑙0 + uint8_t config_index; + uint16_t sequence_id; + uint8_t bandwidth_index; + uint8_t comb_size; + uint8_t comb_offset;//Transmission comb offset 𝑘 ̄ TC [TS38.211, Sec 6.4.1.4.3] Value: 0 → 1 (combSize = 0) Value: 0 → 3 (combSize = 1) + uint8_t cyclic_shift; + uint8_t frequency_position; + uint8_t frequency_shift; + uint8_t frequency_hopping; + uint8_t group_or_sequence_hopping;//Group or sequence hopping configuration (RRC parameter groupOrSequenceHopping in SRS-Resource + uint8_t resource_type;//Type of SRS resource allocation + uint16_t t_srs;//SRS-Periodicity in slots [TS38.211 Sec 6.4.1.4.4] Value: 1,2,3,4,5,8,10,16,20,32,40,64,80,160,320,640,1280,2560 + uint16_t t_offset;//Slot offset value [TS38.211, Sec 6.4.1.4.3] Value:0->2559 + + nfapi_nr_ul_beamforming_t beamforming; + +} nfapi_nr_srs_pdu_t; + +// + +typedef enum { + NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE = 0, + NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE = 1, + NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE = 2, + NFAPI_NR_DL_TTI_SSB_PDU_TYPE = 3, +} nfapi_nr_dl_tti_pdu_type_e; + +typedef enum { + NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE=0, + NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE, + NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE, + NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE, +} nfapi_nr_ul_config_pdu_type_e; + +typedef struct +{ + uint16_t pdu_type;//0: PRACH PDU, 1: PUSCH PDU, 2: PUCCH PDU, 3: SRS PDU + uint16_t pdu_size;//Value: 0 -> 65535 + union + { + nfapi_nr_prach_pdu_t prach_pdu; + nfapi_nr_pusch_pdu_t pusch_pdu; + nfapi_nr_pucch_pdu_t pucch_pdu; + nfapi_nr_srs_pdu_t srs_pdu; + }; + +} nfapi_nr_ul_tti_request_number_of_pdus_t; + +typedef struct +{ + uint8_t pdu_idx;//This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 65535 + +} nfapi_nr_ul_tti_request_number_of_ue_t; + +typedef struct +{ + uint8_t n_ue;//Number of UE in this group For SU-MIMO, one group includes one UE only. For MU-MIMO, one group includes up to 12 UEs. Value 1 -> 6 + nfapi_nr_ul_tti_request_number_of_ue_t ue_list[NFAPI_MAX_NUM_UL_UE_PER_GROUP]; + +} nfapi_nr_ul_tti_request_number_of_groups_t; + +typedef struct { + uint16_t SFN; //0->1023 + uint16_t Slot;//0->319 + uint8_t n_pdus;//Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255 + uint8_t rach_present;//Indicates if a RACH PDU will be included in this message. 0: no RACH in this slot 1: RACH in this slot + uint8_t n_ulsch;//Number of ULSCH PDUs that are included in this message. + uint8_t n_ulcch;//Number of ULCCH PDUs + uint8_t n_group;//Number of UE Groups included in this message. Value 0 -> 8 + nfapi_nr_ul_tti_request_number_of_pdus_t pdus_list[NFAPI_MAX_NUM_UL_PDU]; + nfapi_nr_ul_tti_request_number_of_groups_t groups_list[NFAPI_MAX_NUM_GROUPS]; +} nfapi_nr_ul_tti_request_t; + +//3.4.4 ul_dci_request + +//table 3-54 + +/* +typedef struct +{ + uint16_t pdu_type;//0: PDCCH PDU + uint16_t pdu_size; + nfapi_nr_dl_pdu_configuration_t* phcch_pdu_configuration; + +} nfapi_nr_ul_dci_request_number_of_pdus_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint8_t num_pdus; + nfapi_nr_ul_dci_request_number_of_pdus_t* pdu_list; + +} nfapi_nr_ul_dci_request_t; +*/ + + // normally one PDU per coreset per BWP +#define NFAPI_NR_MAX_UL_DCI_PDUS 4 + +typedef struct { + /// only possible value 0: PDCCH PDU + uint16_t PDUType; + ///Size of the PDU control information (in bytes). This length value includes the 4 bytes required for the PDU type and PDU size parameters. Value 0 -> 65535 + uint16_t PDUSize; + nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu; +} nfapi_nr_ul_dci_request_pdus_t; + +typedef struct { + uint16_t SFN; + uint16_t Slot; + uint8_t numPdus; + nfapi_nr_ul_dci_request_pdus_t ul_dci_pdu_list[NFAPI_NR_MAX_UL_DCI_PDUS]; +} nfapi_nr_ul_dci_request_t; + +//3.4.5 slot_errors +typedef enum { + NFAPI_NR_SLOT_UL_TTI_MSG_INVALID_STATE, + NFAPI_NR_SLOT_UL_TTI_SFN_OUT_OF_SYNC, + NFAPI_NR_SLOT_UL_TTI_MSG_BCH_MISSING, + NFAPI_NR_SLOT_UL_TTI_MSG_SLOT_ERR + +} nfapi_nr_slot_errors_ul_tti_e; + +typedef enum { + NFAPI_NR_SLOT_DL_TTI_MSG_INVALID_STATE, + NFAPI_NR_SLOT_DL_TTI_MSG_SLOT_ERR + +} nfapi_nr_slot_errors_dl_tti_e; + + +typedef enum { + NFAPI_NR_SLOT_UL_DCI_MSG_INVALID_STATE, + NFAPI_NR_SLOT_UL_DCI_MSG_INVALID_SFN, + NFAPI_NR_SLOT_UL_DCI_MSG_UL_DCI_ERR + +} nfapi_nr_slot_errors_ul_dci_e; + +//3.4.6 tx_data_request + +//table 3-58 +#define NFAPI_NR_MAX_TX_REQUEST_TLV 2 +typedef struct +{ + uint16_t PDU_length; + uint16_t PDU_index; + uint32_t num_TLV; + nfapi_nr_tx_data_request_tlv_t TLVs[NFAPI_NR_MAX_TX_REQUEST_TLV]; + +} nfapi_nr_pdu_t; + +#define NFAPI_NR_MAX_TX_REQUEST_PDUS 16 +typedef struct +{ + uint16_t SFN; + uint16_t Slot; + uint16_t Number_of_PDUs; + nfapi_nr_pdu_t pdu_list[NFAPI_NR_MAX_TX_REQUEST_PDUS]; + +} nfapi_nr_tx_data_request_t; + +typedef enum { + NFAPI_NR_DL_DATA_MSG_INVALID_STATE, + NFAPI_NR_DL_DATA_MSG_INVALID_SFN, + NFAPI_NR_DL_DATA_MSG_TX_ERR + +} nfapi_nr_dl_data_errors_e; + +//section 3.4.7 rx_data_indication + +//table 3-61 + +typedef struct +{ + uint32_t handle; + uint16_t rnti; + uint8_t harq_id; + uint16_t pdu_length; + uint8_t ul_cqi; + uint16_t timing_advance;//Timing advance 𝑇𝐴 measured for the UE [TS 38.213, Section 4.2] NTA_new = NTA_old + (TA − 31) ⋅ 16 ⋅ 64⁄2μ Value: 0 → 63 0xffff should be set if this field is invalid + uint16_t rssi; + //variable ! fixme + uint32_t pdu; //MAC PDU + +} nfapi_nr_rx_data_pdu_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint16_t number_of_pdus; + nfapi_nr_rx_data_pdu_t* pdu_list; + +} nfapi_nr_rx_data_indication_t; + +//3.4.8 crc_indication +//table 3-62 +typedef struct +{ + uint32_t handle; + uint16_t rnti; + uint8_t harq_id; + uint8_t tb_crc_status; + uint16_t num_cb;//If CBG is not used this parameter can be set to zero. Otherwise the number of CBs in the TB. Value: 0->65535 + //! fixme + uint8_t* cb_crc_status;//cb_crc_status[ceil(NumCb/8)]; + uint8_t ul_cqi; + uint16_t timing_advance; + uint16_t rssi; + +} nfapi_nr_crc_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint16_t number_crcs; + nfapi_nr_crc_t* crc_list; + +} nfapi_nr_crc_indication_t; + +//3.4.9 uci_indication + +//table 3-67 +typedef struct +{ + uint8_t sr_indication; + uint8_t sr_confidence_level; + +} nfapi_nr_sr_pdu_0_1_t; +//table 3-69 +typedef struct +{ + uint16_t sr_bit_len; + //! fixme + uint8_t* sr_payload;//sr_payload[ceil(sr_bit_len/8)]; + +} nfapi_nr_sr_pdu_2_3_4_t; +//table 3-68 +typedef struct +{ + uint8_t harq_value;//Indicates result on HARQ data. Value: 0 = pass 1 = fail 2 = not present + +} nfapi_nr_harq_t; + +//table 3-70 +typedef struct +{ + uint8_t harq_crc; + uint16_t harq_bit_len; + //! fixme + uint8_t* harq_payload;//harq_payload[ceil(harq_bit_len)]; +} nfapi_nr_harq_pdu_2_3_4_t; + +typedef struct +{ + uint8_t num_harq; + uint8_t harq_confidence_level; + nfapi_nr_harq_t* harq_list; + +} nfapi_nr_harq_pdu_0_1_t; + +//table 3-71 +typedef struct +{ + uint8_t csi_part1_crc; + uint16_t csi_part1_bit_len; + //! fixme + uint8_t* csi_part1_payload;//uint8_t[ceil(csiPart1BitLen/8)] + +} nfapi_nr_csi_part1_pdu_t; + +//table 3-72 +typedef struct +{ + uint8_t csi_part2_crc; + uint16_t csi_part2_bit_len; + //! fixme + uint8_t* csi_part2_payload;//uint8_t[ceil(csiPart2BitLen/8)] +} nfapi_nr_csi_part2_pdu_t; + +//table 3-63 + + //for dci_pusch_pdu +typedef struct +{ + uint8_t pdu_bit_map; + uint32_t handle; + uint16_t rnti; + uint8_t ul_cqi; + uint16_t timing_advance; + uint16_t rssi; + nfapi_nr_harq_pdu_2_3_4_t harq;//table 3-70 + nfapi_nr_csi_part1_pdu_t csi_part1;//71 + nfapi_nr_csi_part2_pdu_t csi_part2;//72 + +}nfapi_nr_uci_pusch_pdu_t; + +//for PUCCH PDU Format 0/1 +typedef struct +{ + uint8_t pdu_bit_map; + uint32_t handle; + uint16_t rnti; + uint8_t pucch_format;//PUCCH format Value: 0 -> 1 0: PUCCH Format0 1: PUCCH Format1 + uint8_t ul_cqi; + uint16_t timing_advance; + uint16_t rssi; + nfapi_nr_sr_pdu_0_1_t sr;//67 + nfapi_nr_harq_pdu_0_1_t harq;//68 + + +}nfapi_nr_uci_pucch_pdu_format_0_1_t; + +//PUCCH PDU Format 2/3/4 +typedef struct +{ + uint8_t pdu_bit_map; + uint32_t handle; + uint16_t rnti; + uint8_t pucch_format;//PUCCH format Value: 0 -> 2 0: PUCCH Format2 1: PUCCH Format3 2: PUCCH Format4 + uint8_t ul_cqi; + uint16_t timing_advance; + uint16_t rssi; + nfapi_nr_sr_pdu_2_3_4_t sr;//69 + nfapi_nr_harq_pdu_2_3_4_t harq;//70 + nfapi_nr_csi_part1_pdu_t csi_part1;//71 + nfapi_nr_csi_part2_pdu_t csi_part2;//72 + +}nfapi_nr_uci_pucch_pdu_format_2_3_4_t; + +//for SR, HARQ and CSI Part 1/ 2 PDUs + +typedef struct +{ + nfapi_nr_uci_pusch_pdu_t* pusch_pdu; + nfapi_nr_uci_pucch_pdu_format_0_1_t* pucch_pdu_format_0_1; + nfapi_nr_uci_pucch_pdu_format_2_3_4_t* pucch_pdu_format_2_3_4; + nfapi_nr_sr_pdu_0_1_t* sr_pdu_0_1; + nfapi_nr_sr_pdu_2_3_4_t* sr_pdu_2_3_4; + nfapi_nr_harq_pdu_0_1_t* harq_pdu_0_1; + nfapi_nr_harq_pdu_2_3_4_t* harq_pdu_2_3_4; + nfapi_nr_csi_part1_pdu_t* csi_part1_pdu; + nfapi_nr_csi_part2_pdu_t* csi_part2_pdu; + +} nfapi_nr_uci_pdu_information_t; + +typedef struct +{ + uint16_t pdu_type; + uint16_t pdu_size; + nfapi_nr_uci_pdu_information_t uci_pdu; + +} nfapi_nr_uci_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint16_t num_ucis; + nfapi_nr_uci_t* uci_list; + +} nfapi_nr_uci_indication_t; + +//3.4.10 srs_indication +//table 3-73 + +typedef struct +{ + uint8_t rb_snr; +}nfapi_nr_srs_indication_reported_symbol_resource_block_t; + +typedef struct +{ + uint16_t num_rbs; + nfapi_nr_srs_indication_reported_symbol_resource_block_t* rb_list; +}nfapi_nr_srs_indication_reported_symbol_t; + + +typedef struct +{ + uint32_t handle; + uint16_t rnti; + uint16_t timing_advance; + uint8_t num_symbols; + uint8_t wide_band_snr; + uint8_t num_reported_symbols; + nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list; + +}nfapi_nr_srs_indication_pdu_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint8_t number_of_pdus; + nfapi_nr_srs_indication_pdu_t* pdu_list; + +} nfapi_nr_srs_indication_t; + + +//3.4.11 rach_indication +//table 3-74 +typedef struct +{ + uint8_t preamble_index; + uint16_t timing_advance; + uint32_t preamble_pwr; + +} nfapi_nr_prach_indication_preamble_t; + +typedef struct{ + uint16_t phy_cell_id; + uint8_t symbol_index; + uint8_t slot_index; + uint8_t freq_index; + uint8_t avg_rssi; + uint8_t avg_snr; + uint8_t num_preamble; + nfapi_nr_prach_indication_preamble_t* preamble_list; + +}nfapi_nr_prach_indication_pdu_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint8_t number_of_pdus; + nfapi_nr_prach_indication_pdu_t* pdu_list; + +} nfapi_nr_rach_indication_t; + +#endif diff --git a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h index 5d463afdae..5abf6b75c3 100644 --- a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h +++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h @@ -18,7 +18,8 @@ #define _NFAPI_VNF_INTERFACE_H_ #include "nfapi_interface.h" -#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" + #include "debug.h" #include "netinet/in.h" @@ -938,7 +939,7 @@ int nfapi_vnf_p7_del_pnf(nfapi_vnf_p7_config_t* config, int phy_id); * may be released after this function call has returned or at a later pointer */ int nfapi_vnf_p7_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_dl_config_request_t* req); -int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_config_request_t* req); +int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req); /*! Send the UL_CONFIG.request * \param config A pointer to the vnf p7 configuration diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c index 8b60122483..35bd5e4c1b 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c @@ -482,7 +482,7 @@ int nfapi_vnf_p7_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_dl_config_re return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header); } -int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_config_request_t* req) +int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(config:%p req:%p)\n", __FUNCTION__, config, req); diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index 6db9548dbe..ed8dd3b49a 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -23,13 +23,14 @@ #include #include #include - #include "assertions.h" #include "SIMULATION/TOOLS/sim.h" #include "PHY/CODING/nrLDPC_encoder/defs.h" #include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h" +#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" #define MAX_NUM_DLSCH_SEGMENTS 16 +#define MAX_BLOCK_LENGTH 8448 #ifndef malloc16 # ifdef __AVX2__ @@ -42,7 +43,6 @@ #define NR_LDPC_PROFILER_DETAIL #define NR_LDPC_ENABLE_PARITY_CHECK - // 4-bit quantizer char quantize4bit(double D,double x) { @@ -76,31 +76,15 @@ char quantize8bit(double D,double x) return((char)qxd); } -char quantize(double D,double x,unsigned char B) -{ - double qxd; - short maxlev; - qxd = floor(x/D); - - maxlev = 1<<(B-1);//(char)(pow(2,B-1)); - - //printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev); - - if (qxd <= -maxlev) - qxd = -maxlev; - else if (qxd >= maxlev) - qxd = maxlev-1; - - return((char)qxd); -} - typedef struct { -double n_iter_mean; -double n_iter_std; -int n_iter_max; + double n_iter_mean; + double n_iter_std; + int n_iter_max; } n_iter_stats_t; -#define MAX_BLOCK_LENGTH 8448 +RAN_CONTEXT_t RC; +PHY_VARS_UE ***PHY_vars_UE_g; +uint16_t NB_UE_INST = 1; short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; @@ -118,7 +102,7 @@ int test_ldpc(short No_iteration, unsigned int *crc_misses, time_stats_t *time_optim, time_stats_t *time_decoder, - n_iter_stats_t * dec_iter) + n_iter_stats_t *dec_iter) { //clock initiate //time_stats_t time,time_optim,tinput,tprep,tparity,toutput, time_decoder; @@ -146,12 +130,12 @@ int test_ldpc(short No_iteration, double *modulated_input[MAX_NUM_DLSCH_SEGMENTS]; char *channel_output_fixed[MAX_NUM_DLSCH_SEGMENTS]; unsigned int i,j,trial=0; - short BG,Zc,Kb,nrows;//,ncols; + short BG=0,nrows=0;//,ncols; int no_punctured_columns,removed_bit; - int i1; + int i1,Zc,Kb=0; int R_ind = 0; //Table of possible lifting sizes -//short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; + //short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; //int n_segments=1; int code_rate_vec[8] = {15, 13, 25, 12, 23, 34, 56, 89}; //double code_rate_actual_vec[8] = {0.2, 0.33333, 0.4, 0.5, 0.66667, 0.73333, 0.81481, 0.88}; @@ -227,15 +211,15 @@ int test_ldpc(short No_iteration, //determine number of bits in codeword if (block_length>3840) { - BG=1; + BG = 1; Kb = 22; - nrows=46; //parity check bits + nrows = 46; //parity check bits //ncols=22; //info bits } else if (block_length<=3840) { - BG=2; - nrows=42; //parity check bits + BG = 2; + nrows = 42; //parity check bits //ncols=10; // info bits if (block_length>640) @@ -246,7 +230,7 @@ int test_ldpc(short No_iteration, Kb = 8; else Kb = 6; - } + } if (nom_rate == 1) if (denom_rate == 5) @@ -298,12 +282,12 @@ int test_ldpc(short No_iteration, } } - printf("ldpc_test: codeword_length %d, n_segments %d, block_length %d, BG %d, Zc %d, Kb %d\n",n_segments *block_length, n_segments, block_length,BG, Zc, Kb); + printf("ldpc_test: codeword_length %d, n_segments %d, block_length %d, BG %d, Zc %d, Kb %d\n",n_segments *block_length, n_segments, block_length, BG, Zc, Kb); no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc; // printf("puncture:%d\n",no_punctured_columns); removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate)); if (ntrials==0) - ldpc_encoder_orig(test_input[0],channel_input[0], block_length, BG, 1); + ldpc_encoder_orig(test_input[0],channel_input[0], Zc, BG, block_length, BG, 1); for (trial=0; trial < ntrials; trial++) { @@ -311,30 +295,30 @@ int test_ldpc(short No_iteration, //// encoder start_meas(&time); for(j=0;j 3840) { - BG=1; + BG = 1; Kb = 22; //nrows=46; //parity check bits //ncols=22; //info bits } else if (block_length<=3840) { - BG=2; + BG = 2; //nrows=42; //parity check bits //ncols=10; // info bits @@ -663,8 +646,7 @@ int main(int argc, char *argv[]) fprintf(fd,"SNR BLER BER UNCODED_BER ENCODER_MEAN ENCODER_STD ENCODER_MAX DECODER_TIME_MEAN DECODER_TIME_STD DECODER_TIME_MAX DECODER_ITER_MEAN DECODER_ITER_STD DECODER_ITER_MAX\n"); - for (SNR=SNR0;SNR n_iter_mean); printf("SNR %f, Std iterations: %f\n",SNR, dec_iter->n_iter_std); printf("SNR %f, Max iterations: %d\n",SNR, dec_iter->n_iter_max); @@ -720,23 +702,11 @@ int main(int argc, char *argv[]) dec_iter->n_iter_max ); - if (decoded_errors[i] == 0) - break; + if (decoded_errors[i] == 0) break; + i=i+1; - - } fclose(fd); return(0); } - - - - - - - - - - diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index 76cde6c3be..cb3f427f24 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -11,6 +11,7 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h" #include "PHY/CODING/coding_defs.h" #include "SIMULATION/TOOLS/sim.h" +#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" //#include "PHY/NR_TRANSPORT/nr_transport.h" //#include "common/utils/LOG/log.h" @@ -18,7 +19,12 @@ //#define DEBUG_POLAR_TIMING //#define DEBUG_POLARTEST -int main(int argc, char *argv[]) { +RAN_CONTEXT_t RC; +PHY_VARS_UE ***PHY_vars_UE_g; +uint16_t NB_UE_INST = 1; + +int main(int argc, char *argv[]) +{ //Default simulation values (Aim for iterations = 1000000.) int decoder_int16=0; int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI @@ -169,7 +175,7 @@ if (logFlag){ double channelOutput[coderLength]; //add noise int16_t channelOutput_int16[coderLength]; - t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level); + t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, 1, aggregation_level,NULL); #ifdef DEBUG_DCI_POLAR_PARAMS uint32_t dci_pdu[4]; @@ -235,8 +241,8 @@ if (logFlag){ start_meas(&timeEncoder); if (decoder_int16==1) { - polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, currentPtr); - //polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0, currentPtr); + polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, 0, currentPtr); + //polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0,0,currentPtr); } else { //0 --> PBCH, 1 --> DCI, -1 --> UCI if (polarMessageType == 0) polar_encoder(testInput, encoderOutput, currentPtr); @@ -272,7 +278,7 @@ if (logFlag){ start_meas(&timeDecoder); if (decoder_int16==1) { - decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, currentPtr); + decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, 0, currentPtr); } else { //0 --> PBCH, 1 --> DCI, -1 --> UCI if (polarMessageType == 0) { decoderState = polar_decoder(channelOutput, diff --git a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c index ee1a228ab8..02d5dc64e0 100644 --- a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c +++ b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c @@ -1,27 +1,16 @@ -#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h" -#include "SIMULATION/TOOLS/sim.h" #include +#include "SIMULATION/TOOLS/sim.h" +#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h" +#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" //#define DEBUG_SMALLBLOCKTEST -signed char quantize(double D, double x, unsigned char B) +RAN_CONTEXT_t RC; +PHY_VARS_UE ***PHY_vars_UE_g; +uint16_t NB_UE_INST = 1; + +int main(int argc, char *argv[]) { - double qxd; - short maxlev; - qxd = floor(x/D); - - maxlev = 1<<(B-1);//(char)(pow(2,B-1)); - - if (qxd <= -maxlev) - qxd = -maxlev; - else if (qxd >= maxlev) - qxd = maxlev-1; - - return((char)qxd); -} - -int main(int argc, char *argv[]) { - time_stats_t timeEncoder,timeDecoder; opp_enabled=1; cpu_freq_GHz = get_cpu_freq_GHz(); diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h index 3e6222c341..00708ed60c 100644 --- a/openair1/PHY/CODING/coding_defs.h +++ b/openair1/PHY/CODING/coding_defs.h @@ -38,7 +38,7 @@ #define MAX_TURBO_ITERATIONS_MBSFN 8 #define MAX_TURBO_ITERATIONS max_turbo_iterations -#define MAX_LDPC_ITERATIONS 5 +#define MAX_LDPC_ITERATIONS 10//5 #define MAX_LDPC_ITERATIONS_MBSFN 4 #define LTE_NULL 2 @@ -454,14 +454,21 @@ int32_t nr_segmentation(unsigned char *input_buffer, unsigned int *C, unsigned int *K, unsigned int *Zout, - unsigned int *F); + unsigned int *F, + uint8_t BG); -uint32_t nr_compute_tbs(uint8_t mcs, - uint16_t nb_rb, - uint16_t nb_symb_sch, - uint8_t nb_re_dmrs, - uint16_t length_dmrs, - uint8_t Nl); +uint32_t nr_compute_tbs(uint16_t Qm, + uint16_t R, + uint16_t nb_rb, + uint16_t nb_symb_sch, + uint16_t nb_dmrs_prb, + uint16_t nb_rb_oh, + uint8_t Nl); + +uint32_t nr_compute_tbslbrm(uint16_t table, + uint16_t nb_rb, + uint8_t Nl, + uint8_t C); void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f); @@ -474,6 +481,8 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm, uint8_t *w, uint8_t *e, uint8_t C, + uint32_t F, + uint32_t Foffset, uint8_t rvidx, uint32_t E); @@ -486,7 +495,9 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm, uint8_t C, uint8_t rvidx, uint8_t clear, - uint32_t E); + uint32_t E, + uint32_t F, + uint32_t Foffset); decoder_if_t phy_threegpplte_turbo_decoder; decoder_if_t phy_threegpplte_turbo_decoder8; diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h index 00e8fd98d5..878150a9a8 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h @@ -47,7 +47,7 @@ static inline void nrLDPC_bnProcPc(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_proc int8_t* bnProcBufRes = p_procBuf->bnProcBufRes; int8_t* llrRes = p_procBuf->llrRes; int8_t* llrProcBuf = p_procBuf->llrProcBuf; - + __m128i* p_bnProcBuf; __m256i* p_bnProcBufRes; __m128i* p_llrProcBuf; @@ -1693,7 +1693,7 @@ static inline void nrLDPC_bnProc(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBu int8_t* bnProcBuf = p_procBuf->bnProcBuf; int8_t* bnProcBufRes = p_procBuf->bnProcBufRes; int8_t* llrRes = p_procBuf->llrRes; - + __m256i* p_bnProcBuf; __m256i* p_bnProcBufRes; __m256i* p_llrRes; @@ -2775,24 +2775,35 @@ static inline void nrLDPC_llr2bit(int8_t* out, int8_t* llrOut, uint16_t numLLR) } /** - \brief Performs hard-decision on output LLRs and packs the output in 32 bit values. + \brief Performs hard-decision on output LLRs and packs the output in byte aligned output according to TS 38.321 Section 6.1.1. + i = 0,1,2,... + IN[i] : a0, a1, a2, ..., a_{A-1} + OUT[i]: a7,a6,a5,a4,a3,a2,a1,a0|a15,14,...,a8|a23,a22,...,a16|a31,a30,...,a24|... \param out Pointer hard-decision output, every int8_t contains 8 bits \param llrOut Pointer to output LLRs \param numLLR Number of LLRs */ 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}; + __m256i* p_llrOut = (__m256i*) llrOut; uint32_t* p_bits = (uint32_t*) out; + __m256i inPerm; int8_t* p_llrOut8; uint32_t bitsTmp = 0; uint32_t i; uint32_t M = numLLR>>5; uint32_t Mr = numLLR&31; + const __m256i* p_shuffle = (__m256i*) constShuffle_256_epi8; for (i=0; i 640) - Kb = 10; - else if (block_length>560) - Kb = 9; - else if (block_length>192) - Kb = 8; - else - Kb = 6; } - //find minimum value in all sets of lifting size - Zc=0; - for (i1=0; i1 < 51; i1++) - { - if (lift_size[i1] >= (double) block_length/Kb) - { - Zc = lift_size[i1]; - //printf("%d\n",Zc); - break; - } - } - AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length); #ifdef DEBUG_LDPC LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d\n",BG,Zc,Kb,block_length); @@ -263,8 +241,8 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3); + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); // printf("%d\n",no_punctured_columns); // printf("%d\n",removed_bit); // unpack input @@ -273,7 +251,7 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh if(tinput != NULL) start_meas(tinput); for (i=0; i >(i&7); + c[i] = (test_input[i/8]&(128>>(i&7)))>>(7-(i&7)); //printf("c(%d,%d)=%d\n",j,i,temp); } @@ -317,20 +295,18 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh return 0; } -int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) +int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) { - short Zc,Kb=0,nrows=0,ncols=0; - int i,i1,j; + short nrows=0,ncols=0; + int i,i1,j,rate=3; int no_punctured_columns,removed_bit; - //Table of possible lifting sizes - short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; char temp; int simd_size; #ifdef __AVX2__ __m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000); - __m256i andmask = _mm256_set1_epi64x(0x8040201008040201); // every 8 bits -> 8 bytes, pattern repeats. + __m256i andmask = _mm256_set1_epi64x(0x0102040810204080); // every 8 bits -> 8 bytes, pattern repeats. __m256i zero256 = _mm256_setzero_si256(); __m256i masks[8]; register __m256i c256; @@ -350,10 +326,9 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i //if (block_length>3840) if (BG==1) { - //BG=1; - Kb = 22; nrows=46; //parity check bits ncols=22; //info bits + rate=3; } //else if (block_length<=3840) else if (BG==2) @@ -361,28 +336,9 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i //BG=2; nrows=42; //parity check bits ncols=10; // info bits - - if (block_length>640) - Kb = 10; - else if (block_length>560) - Kb = 9; - else if (block_length>192) - Kb = 8; - else - Kb = 6; - } + rate=5; - //find minimum value in all sets of lifting size - Zc=0; - for (i1=0; i1 < 51; i1++) - { - if (lift_size[i1] >= (double) block_length/Kb) - { - Zc = lift_size[i1]; - //printf("%d\n",Zc); - break; - } - } + } #ifdef DEBUG_LDPC LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments); @@ -400,8 +356,8 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3); + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); // printf("%d\n",no_punctured_columns); // printf("%d\n",removed_bit); // unpack input @@ -413,7 +369,7 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i for (i=0; i >(i&7); + temp = (test_input[j][i/8]&(128>>(i&7)))>>(7-(i&7)); //printf("c(%d,%d)=%d\n",j,i,temp); c[i] |= (temp << j); } @@ -431,7 +387,7 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i for (i=(block_length>>5)<<5;i >(i&7); + temp = (test_input[j][i/8]&(128>>(i&7)))>>(7-(i&7)); //printf("c(%d,%d)=%d\n",j,i,temp); c[i] |= (temp << j); } @@ -517,14 +473,13 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i return 0; } -int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) +int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) { - short Zc,Kb=0,nrows=0,ncols=0; - int i,i1,j; + short nrows=0,ncols=0; + int i,i1,j,rate=3; int no_punctured_columns,removed_bit; //Table of possible lifting sizes - short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; char temp; int simd_size; int macro_segment, macro_segment_end; @@ -537,7 +492,7 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha #ifdef __AVX2__ __m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000); - __m256i andmask = _mm256_set1_epi64x(0x8040201008040201); // every 8 bits -> 8 bytes, pattern repeats. + __m256i andmask = _mm256_set1_epi64x(0x0102040810204080); // every 8 bits -> 8 bytes, pattern repeats. __m256i zero256 = _mm256_setzero_si256(); __m256i masks[8]; register __m256i c256; @@ -556,38 +511,16 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha //determine number of bits in codeword if (BG==1) { - BG=1; - Kb = 22; nrows=46; //parity check bits ncols=22; //info bits + rate=3; } else if (BG==2) { - BG=2; nrows=42; //parity check bits ncols=10; // info bits - - if (block_length>640) - Kb = 10; - else if (block_length>560) - Kb = 9; - else if (block_length>192) - Kb = 8; - else - Kb = 6; - } - - //find minimum value in all sets of lifting size - Zc=0; - for (i1=0; i1 < 51; i1++) - { - if (lift_size[i1] >= (double) block_length/Kb) - { - Zc = lift_size[i1]; - //printf("%d\n",Zc); - break; + rate=5; } - } #ifdef DEBUG_LDPC LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments); @@ -605,10 +538,10 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3); - // printf("%d\n",no_punctured_columns); - // printf("%d\n",removed_bit); + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); + //printf("%d\n",no_punctured_columns); + //printf("%d\n",removed_bit); // unpack input memset(c,0,sizeof(unsigned char) * ncols * Zc); memset(d,0,sizeof(unsigned char) * nrows * Zc); @@ -639,7 +572,7 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha //for (j=0; j >(i&7); + temp = (test_input[j][i/8]&(128>>(i&7)))>>(7-(i&7)); //printf("c(%d,%d)=%d\n",j,i,temp); c[i] |= (temp << (j-macro_segment)); } diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c index 13318c9d5d..5da223dc64 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c @@ -361,24 +361,19 @@ short *choose_generator_matrix(short BG,short Zc) return Gen_shift_values; } -int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length, short BG,unsigned char gen_code) +int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length, short BG,unsigned char gen_code) { unsigned char c[22*384]; //padded input, unpacked, max size unsigned char d[68*384]; //coded output, unpacked, max size unsigned char channel_temp,temp; short *Gen_shift_values, *no_shift_values, *pointer_shift_values; - short Zc; - //initialize for BG == 1 - short Kb = 22; + short nrows = 46;//parity check bits short ncols = 22;//info bits int i,i1,i2,i3,i4,i5,temp_prime,var; - int no_punctured_columns,removed_bit; - //Table of possible lifting sizes - short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; - + int no_punctured_columns,removed_bit,rate=3; int nind=0; int indlist[1000]; int indlist2[1000]; @@ -387,10 +382,9 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho //if (block_length>3840) if (BG==1) { - //BG=1; - Kb = 22; nrows=46; //parity check bits ncols=22; //info bits + rate=3; } //else if (block_length<=3840) else if (BG==2) @@ -398,33 +392,9 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho //BG=2; nrows=42; //parity check bits ncols=10; // info bits - - if (block_length>640) - Kb = 10; - else if (block_length>560) - Kb = 9; - else if (block_length>192) - Kb = 8; - else - Kb = 6; + rate=5; } - //find minimum value in all sets of lifting size - Zc=0; - for (i1=0; i1 < 51; i1++) - { - if (lift_size[i1] >= (double) block_length/Kb) - { - Zc = lift_size[i1]; - //printf("%d\n",Zc); - break; - } - } - if (Zc==0) { - printf("ldpc_encoder_orig: could not determine lifting size\n"); - return(-1); - } - Gen_shift_values=choose_generator_matrix(BG,Zc); if (Gen_shift_values==NULL) { printf("ldpc_encoder_orig: could not find generator matrix\n"); @@ -445,11 +415,11 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho pointer_shift_values=(short *) pointer_shift_values_BG2; } else { - AssertFatal(0,"BG %d is not supported yet\n",BG); + AssertFatal(0,"BG %d is not supported yet\n",BG); } - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*3); + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*rate); //printf("%d\n",no_punctured_columns); //printf("%d\n",removed_bit); // unpack input @@ -460,7 +430,7 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho { //c[i] = test_input[i/8]<<(i%8); //c[i]=c[i]>>7&1; - c[i]=(test_input[i/8]&(1<<(i&7)))>>(i&7); + c[i]=(test_input[i/8]&(128>>(i&7)))>>(7-(i&7)); } // parity check part diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 66d0fc481c..7ec530242e 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -601,7 +601,9 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) { uint32_t polar_decoder_int16(int16_t *input, uint64_t *out, - const t_nrPolar_params *polarParams) { + uint8_t ones_flag, + const t_nrPolar_params *polarParams) +{ int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); nr_polar_rate_matching_int16(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); @@ -645,32 +647,46 @@ uint32_t polar_decoder_int16(int16_t *input, //int len_mod64=len&63; int crclen = polarParams->crcParityBits; uint64_t rxcrc=B[0]&((1< >crclen); - uint8_t A32_flip[4]; + uint8_t A32_flip[4+offset]; + if (ones_flag) { + A32_flip[0] = 0xff; + A32_flip[1] = 0xff; + A32_flip[2] = 0xff; + } uint32_t Aprime= (uint32_t)(Ar<<(32-len)); - A32_flip[0]=((uint8_t *)&Aprime)[3]; - A32_flip[1]=((uint8_t *)&Aprime)[2]; - A32_flip[2]=((uint8_t *)&Aprime)[1]; - A32_flip[3]=((uint8_t *)&Aprime)[0]; - crc = (uint64_t)(crc24c(A32_flip,len)>>8); + A32_flip[0+offset]=((uint8_t *)&Aprime)[3]; + A32_flip[1+offset]=((uint8_t *)&Aprime)[2]; + A32_flip[2+offset]=((uint8_t *)&Aprime)[1]; + A32_flip[3+offset]=((uint8_t *)&Aprime)[0]; + crc = (uint64_t)(crc24c(A32_flip,8*offset+len)>>8); } else if (len<=64) { Ar = (B[0]>>crclen) | (B[1]<<(64-crclen));; - uint8_t A64_flip[8]; - uint64_t Aprime= (uint32_t)(Ar<<(64-len)); - A64_flip[0]=((uint8_t *)&Aprime)[7]; - A64_flip[1]=((uint8_t *)&Aprime)[6]; - A64_flip[2]=((uint8_t *)&Aprime)[5]; - A64_flip[3]=((uint8_t *)&Aprime)[4]; - A64_flip[4]=((uint8_t *)&Aprime)[3]; - A64_flip[5]=((uint8_t *)&Aprime)[2]; - A64_flip[6]=((uint8_t *)&Aprime)[1]; - A64_flip[7]=((uint8_t *)&Aprime)[0]; - crc = (uint64_t)(crc24c(A64_flip,len)>>8); + uint8_t A64_flip[8+offset]; + if (ones_flag) { + A64_flip[0] = 0xff; + A64_flip[1] = 0xff; + A64_flip[2] = 0xff; + } + uint64_t Aprime= (uint64_t)(Ar<<(64-len)); + A64_flip[0+offset]=((uint8_t *)&Aprime)[7]; + A64_flip[1+offset]=((uint8_t *)&Aprime)[6]; + A64_flip[2+offset]=((uint8_t *)&Aprime)[5]; + A64_flip[3+offset]=((uint8_t *)&Aprime)[4]; + A64_flip[4+offset]=((uint8_t *)&Aprime)[3]; + A64_flip[5+offset]=((uint8_t *)&Aprime)[2]; + A64_flip[6+offset]=((uint8_t *)&Aprime)[1]; + A64_flip[7+offset]=((uint8_t *)&Aprime)[0]; + crc = (uint64_t)(crc24c(A64_flip,8*offset+len)>>8); } #if 0 diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 493b43ee74..6e01a05d0f 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -148,6 +148,7 @@ void polar_encoder_dci(uint32_t *in, void polar_encoder_fast(uint64_t *A, uint32_t *out, int32_t crcmask, + uint8_t ones_flag, t_nrPolar_params *polarParams); int8_t polar_decoder(double *input, @@ -157,6 +158,7 @@ int8_t polar_decoder(double *input, uint32_t polar_decoder_int16(int16_t *input, uint64_t *out, + uint8_t ones_flag, const t_nrPolar_params *polarParams); int8_t polar_decoder_dci(double *input, @@ -185,7 +187,9 @@ void nr_polar_print_polarParams(t_nrPolar_params *polarParams); t_nrPolar_params *nr_polar_params (int8_t messageType, uint16_t messageLength, - uint8_t aggregation_level); + uint8_t aggregation_level, + int decoder_flag, + t_nrPolar_params **polarList_ext); uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c index 9858f16cb0..8e4b45f744 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c @@ -268,7 +268,7 @@ static inline void polar_rate_matching(t_nrPolar_params *polarParams,void *in,vo #endif for (int i=0; i encoderLength; i++) { #ifdef DEBUG_POLAR_ENCODER - printf("%u<-%u : %llx.%llx =>",i,polarParams->rate_matching_pattern[i],((uint64_t *)out)[1],((uint64_t *)out)[0]); + printf("%d<-%u : %llx.%llx =>",i,polarParams->rate_matching_pattern[i],((uint64_t *)out)[1],((uint64_t *)out)[0]); #endif tmp0 = (*in128&(((uint128_t)1)< rate_matching_pattern[i])); if (tmp0!=0) { @@ -410,6 +410,7 @@ void build_polar_tables(t_nrPolar_params *polarParams) { void polar_encoder_fast(uint64_t *A, uint32_t *out, int32_t crcmask, + uint8_t ones_flag, t_nrPolar_params *polarParams) { AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K); AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K); @@ -421,6 +422,10 @@ void polar_encoder_fast(uint64_t *A, AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n"); //int bitlen0=bitlen; uint64_t tcrc=0; + uint8_t offset = 0; + + // appending 24 ones before a0 for DCI as stated in 38.212 7.3.2 + if (ones_flag) offset = 3; // A bit string should be stored as 0, 0, ..., 0, a'_0, a'_1, ..., a'_A-1, //???a'_{N-1} a'_{N-2} ... a'_{N-A} 0 .... 0, where N=64,128,192,..., N is smallest multiple of 64 greater than or equal to A @@ -428,38 +433,53 @@ void polar_encoder_fast(uint64_t *A, // First flip A bitstring byte endian for CRC routines (optimized for DLSCH/ULSCH, not PBCH/PDCCH) // CRC reads in each byte in bit positions 7 down to 0, for PBCH/PDCCH we need to read in a_{A-1} down to a_{0}, A = length of bit string (e.g. 32 for PBCH) if (bitlen<=32) { - uint8_t A32_flip[4]; + uint8_t A32_flip[4+offset]; + if (ones_flag) { + A32_flip[0] = 0xff; + A32_flip[1] = 0xff; + A32_flip[2] = 0xff; + } uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen)); - A32_flip[0]=((uint8_t *)&Aprime)[3]; - A32_flip[1]=((uint8_t *)&Aprime)[2]; - A32_flip[2]=((uint8_t *)&Aprime)[1]; - A32_flip[3]=((uint8_t *)&Aprime)[0]; - tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,bitlen)>>8))); + A32_flip[0+offset]=((uint8_t *)&Aprime)[3]; + A32_flip[1+offset]=((uint8_t *)&Aprime)[2]; + A32_flip[2+offset]=((uint8_t *)&Aprime)[1]; + A32_flip[3+offset]=((uint8_t *)&Aprime)[0]; + tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,8*offset+bitlen)>>8))); } else if (bitlen<=64) { - uint8_t A64_flip[8]; - uint64_t Aprime= (uint32_t)(((uint64_t)*A)<<(64-bitlen)); - A64_flip[0]=((uint8_t *)&Aprime)[7]; - A64_flip[1]=((uint8_t *)&Aprime)[6]; - A64_flip[2]=((uint8_t *)&Aprime)[5]; - A64_flip[3]=((uint8_t *)&Aprime)[4]; - A64_flip[4]=((uint8_t *)&Aprime)[3]; - A64_flip[5]=((uint8_t *)&Aprime)[2]; - A64_flip[6]=((uint8_t *)&Aprime)[1]; - A64_flip[7]=((uint8_t *)&Aprime)[0]; - tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,bitlen)>>8))); + uint8_t A64_flip[8+offset]; + if (ones_flag) { + A64_flip[0] = 0xff; + A64_flip[1] = 0xff; + A64_flip[2] = 0xff; + } + uint64_t Aprime= (uint64_t)(((uint64_t)*A)<<(64-bitlen)); + A64_flip[0+offset]=((uint8_t *)&Aprime)[7]; + A64_flip[1+offset]=((uint8_t *)&Aprime)[6]; + A64_flip[2+offset]=((uint8_t *)&Aprime)[5]; + A64_flip[3+offset]=((uint8_t *)&Aprime)[4]; + A64_flip[4+offset]=((uint8_t *)&Aprime)[3]; + A64_flip[5+offset]=((uint8_t *)&Aprime)[2]; + A64_flip[6+offset]=((uint8_t *)&Aprime)[1]; + A64_flip[7+offset]=((uint8_t *)&Aprime)[0]; + tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,8*offset+bitlen)>>8))); } else if (bitlen<=128) { - uint8_t A128_flip[16]; - uint128_t Aprime= (uint32_t)(((uint128_t)*A)<<(128-bitlen)); - A128_flip[0]=((uint8_t*)&Aprime)[15]; A128_flip[1]=((uint8_t*)&Aprime)[14]; - A128_flip[2]=((uint8_t*)&Aprime)[13]; A128_flip[3]=((uint8_t*)&Aprime)[12]; - A128_flip[4]=((uint8_t*)&Aprime)[11]; A128_flip[5]=((uint8_t*)&Aprime)[10]; - A128_flip[6] =((uint8_t*)&Aprime)[9]; A128_flip[7] =((uint8_t*)&Aprime)[8]; - A128_flip[8] =((uint8_t*)&Aprime)[7]; A128_flip[9] =((uint8_t*)&Aprime)[6]; - A128_flip[10]=((uint8_t*)&Aprime)[5]; A128_flip[11]=((uint8_t*)&Aprime)[4]; - A128_flip[12]=((uint8_t*)&Aprime)[3]; A128_flip[13]=((uint8_t*)&Aprime)[2]; - A128_flip[14]=((uint8_t*)&Aprime)[1]; A128_flip[15]=((uint8_t*)&Aprime)[0]; - tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,bitlen)>>8))); + uint8_t A128_flip[16+offset]; + if (ones_flag) { + A128_flip[0] = 0xff; + A128_flip[1] = 0xff; + A128_flip[2] = 0xff; + } + uint128_t Aprime= (uint128_t)(((uint128_t)*A)<<(128-bitlen)); + A128_flip[0+offset]=((uint8_t*)&Aprime)[15]; A128_flip[1+offset]=((uint8_t*)&Aprime)[14]; + A128_flip[2+offset]=((uint8_t*)&Aprime)[13]; A128_flip[3+offset]=((uint8_t*)&Aprime)[12]; + A128_flip[4+offset]=((uint8_t*)&Aprime)[11]; A128_flip[5+offset]=((uint8_t*)&Aprime)[10]; + A128_flip[6+offset] =((uint8_t*)&Aprime)[9]; A128_flip[7+offset] =((uint8_t*)&Aprime)[8]; + A128_flip[8+offset] =((uint8_t*)&Aprime)[7]; A128_flip[9+offset] =((uint8_t*)&Aprime)[6]; + A128_flip[10+offset]=((uint8_t*)&Aprime)[5]; A128_flip[11+offset]=((uint8_t*)&Aprime)[4]; + A128_flip[12+offset]=((uint8_t*)&Aprime)[3]; A128_flip[13+offset]=((uint8_t*)&Aprime)[2]; + A128_flip[14+offset]=((uint8_t*)&Aprime)[1]; A128_flip[15+offset]=((uint8_t*)&Aprime)[0]; + tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,8*offset+bitlen)>>8))); } int n; @@ -473,7 +493,6 @@ void polar_encoder_fast(uint64_t *A, //??? b_{N'-1} b_{N'-2} ... b_{N'-A} b_{N'-A-1} ... b_{N'-A-Nparity} = a_{N-1} a_{N-2} ... a_{N-A} p_{N_parity-1} ... p_0 - for (n=0; n crcParityBits) | tcrc; else B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits)); diff --git a/openair1/PHY/CODING/nr_compute_tbs.c b/openair1/PHY/CODING/nr_compute_tbs.c deleted file mode 100644 index e1c15d4a86..0000000000 --- a/openair1/PHY/CODING/nr_compute_tbs.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/* file: nr_compute_tbs.c - purpose: Compute NR TBS - author: Hongzhi WANG (TCL) -*/ -#include "PHY/defs_nr_UE.h" -//#include "SCHED/extern.h" - -#define INDEX_MAX_TBS_TABLE (93) -//Table 5.1.3.1-1 -uint16_t Mcsindextable1[29][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616}, - {4,658},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}}; -//Table 5.1.2.2-2 -uint16_t Tbstable_nr[INDEX_MAX_TBS_TABLE] = {24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,208,224,240,256,272,288,304,320,336,352,368,384,408,432,456,480,504,528,552,576,608,640,672,704,736,768,808,848,888,928,984,1032,1064,1128,1160,1192,1224,1256,1288,1320,1352,1416,1480,1544,1608,1672,1736,1800,1864,1928,2024,2088,2152,2216,2280,2408,2472,2536,2600,2664,2728,2792,2856,2976,3104,3240,3368,3496,3624,3752,3824}; - -uint32_t nr_compute_tbs(uint8_t mcs, - uint16_t nb_rb, - uint16_t nb_symb_sch, - uint8_t nb_re_dmrs, - uint16_t length_dmrs, - uint8_t Nl) -{ - uint16_t nbp_re, nb_re, nb_dmrs_prb, nb_rb_oh,Qm,R; - uint32_t nr_tbs=0; - double Ninfo,Np_info,n,C; - - nb_rb_oh = 0; //set to 0 if not configured by higher layer - Qm = Mcsindextable1[mcs][0]; - R = Mcsindextable1[mcs][1]; - nb_dmrs_prb = nb_re_dmrs*length_dmrs; - - nbp_re = 12 * nb_symb_sch - nb_dmrs_prb - nb_rb_oh; - - nb_re = min(156, nbp_re) * nb_rb; - - // Intermediate number of information bits - Ninfo = (double)((nb_re * R * Qm * Nl)/1024); - - //printf("Ninfo %lf nbp_re %d nb_re %d mcs %d Qm %d, R %d\n", Ninfo, nbp_re, nb_re,mcs, Qm, R); - - if (Ninfo <=3824) { - - n = max(3, floor(log2(Ninfo)) - 6); - Np_info = max(24, pow(2,n) * floor(Ninfo/pow(2,n))); - - for (int i=0; i = Np_info){ - nr_tbs = Tbstable_nr[i]; - break; - } - } - } - else { - n = floor(log2(Ninfo-24)) - 5; - Np_info = max(3840, pow(2,n) * round((Ninfo - 24)/pow(2,n))); - - if (R <= 256) { //1/4 - C = ceil( (Np_info + 24)/3816 ); - nr_tbs = (uint32_t)(8 * C * ceil( (Np_info + 24)/(8*C) ) - 24); - } - else { - if (Np_info > 8424){ - C = ceil( (Np_info + 24)/8424 ); - nr_tbs = (uint32_t)(8 * C * ceil( (Np_info + 24)/(8*C) ) - 24); - } - else { - nr_tbs = (uint32_t)(8 * ceil( (Np_info + 24)/8 ) - 24); - //printf("n %lf Np_info %f pow %f ceil %f \n",n, Np_info,pow(2,6),ceil( (Np_info + 24)/8 )); - } - - } - - } - - return nr_tbs; -} diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c index efc78d91fd..f6a06b3f7f 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nr_polar_init.c @@ -40,7 +40,8 @@ static int intcmp(const void *p1,const void *p2) { static void nr_polar_init(t_nrPolar_params * *polarParams, int8_t messageType, uint16_t messageLength, - uint8_t aggregation_level) { + uint8_t aggregation_level, + int decoder_flag) { t_nrPolar_params *currentPtr = *polarParams; uint16_t aggregation_prime = nr_polar_aggregation_prime(aggregation_level); @@ -150,7 +151,7 @@ static void nr_polar_init(t_nrPolar_params * *polarParams, newPolarInitNode->i_bil, newPolarInitNode->encoderLength); free(J); - build_decoder_tree(newPolarInitNode); + if (decoder_flag == 1) build_decoder_tree(newPolarInitNode); build_polar_tables(newPolarInitNode); init_polar_deinterleaver_table(newPolarInitNode); //printf("decoder tree nodes %d\n",newPolarInitNode->tree.num_nodes); @@ -183,10 +184,13 @@ void nr_polar_print_polarParams(t_nrPolar_params *polarParams) { t_nrPolar_params *nr_polar_params (int8_t messageType, uint16_t messageLength, - uint8_t aggregation_level) { + uint8_t aggregation_level, + int decoding_flag, + t_nrPolar_params **polarList_ext) { static t_nrPolar_params *polarList = NULL; - nr_polar_init(&polarList, messageType,messageLength,aggregation_level); - t_nrPolar_params *polarParams=polarList; + nr_polar_init(polarList_ext != NULL ? polarList_ext : &polarList, + messageType,messageLength,aggregation_level,decoding_flag); + t_nrPolar_params *polarParams=polarList_ext != NULL ? *polarList_ext : polarList; const int tag=messageType * messageLength * nr_polar_aggregation_prime(aggregation_level); while (polarParams != NULL) { diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c index 0954939a58..9691932518 100644 --- a/openair1/PHY/CODING/nr_rate_matching.c +++ b/openair1/PHY/CODING/nr_rate_matching.c @@ -32,23 +32,281 @@ uint8_t index_k0[2][4] = {{0,17,33,56},{0,13,25,43}}; - void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f) { uint32_t EQm; EQm = E/Qm; memset(f,0,E*sizeof(uint8_t)); + uint8_t *e0,*e1,*e2,*e3,*e4,*e5,*e6,*e7; + uint8_t *fp; +#if 0 //def __AVX2__ + __m256i tmp0,tmp1,tmp2,tmp0b,tmp1b,tmp3,tmp4,tmp5; + __m256i *e0_256,*e1_256,*e2_256,*e3_256,*e4_256,*e5_256,*e6_256,*e7_256; - for (int j = 0; j< EQm; j++){ - for (int i = 0; i< Qm; i++){ - f[(i+j*Qm)] = e[(i*EQm + j)]; - } + __m256i *f_256=(__m256i *)f; + + uint8_t *fp2; + switch(Qm) { + case 2: + e0=e; + e1=e0+EQm; + e0_256=(__m256i *)e0; + e1_256=(__m256i *)e1; + for (int k=0,j=0;j >5;j++,k+=2) { + f_256[k] = _mm256_unpacklo_epi8(e0_256[j],e1_256[j]); + f_256[k+1] = _mm256_unpackhi_epi8(e0_256[j],e1_256[j]); + } + break; + case 4: + e0=e; + e1=e0+EQm; + e2=e1+EQm; + e3=e2+EQm; + e0_256=(__m256i *)e0; + e1_256=(__m256i *)e1; + e2_256=(__m256i *)e2; + e3_256=(__m256i *)e3; + for (int k=0,j=0;j >5;j++,k+=4) { + tmp0 = _mm256_unpacklo_epi8(e0_256[j],e1_256[j]); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15) + tmp1 = _mm256_unpacklo_epi8(e2_256[j],e3_256[j]); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15) + f_256[k] = _mm256_unpacklo_epi8(tmp0,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7) + f_256[k+1] = _mm256_unpackhi_epi8(tmp0,tmp1); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15) + tmp0 = _mm256_unpackhi_epi8(e0_256[j],e1_256[j]); // e0(i+16) e1(i+16) e0(i+17) e1(i+17) .... e0(i+31) e1(i+31) + tmp1 = _mm256_unpackhi_epi8(e2_256[j],e3_256[j]); // e2(i+16) e3(i+16) e2(i+17) e3(i+17) .... e2(i+31) e3(i+31) + f_256[k+2] = _mm256_unpacklo_epi8(tmp0,tmp1); + f_256[k+3] = _mm256_unpackhi_epi8(tmp0,tmp1); + } + break; + case 6: + e0=e; + e1=e0+EQm; + e2=e1+EQm; + e3=e2+EQm; + e4=e3+EQm; + e5=e4+EQm; + e0_256=(__m256i *)e0; + e1_256=(__m256i *)e1; + e2_256=(__m256i *)e2; + e3_256=(__m256i *)e3; + e4_256=(__m256i *)e4; + e5_256=(__m256i *)e5; + + for (int j=0,k=0;j >5;j++,k+=192) { + fp = f+k; + fp2 = fp+96; + + tmp0 = _mm256_unpacklo_epi8(e0_256[j],e1_256[j]); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15) + tmp1 = _mm256_unpacklo_epi8(e2_256[j],e3_256[j]); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15) + tmp0b = _mm256_unpacklo_epi16(tmp0,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7) + tmp1b = _mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15) + tmp0 = _mm256_unpacklo_epi8(e4_256[j],e5_256[j]); // e4(i) e5(i) e4(i+1) e5(i+1) .... e4(i+15) e5(i+15) + *((uint32_t*)fp) = _mm256_extract_epi32(tmp0b,0); + *((uint16_t*)(fp+4)) = _mm256_extract_epi16(tmp0,0); + *((uint32_t*)(fp+6)) = _mm256_extract_epi32(tmp0b,1); + *((uint16_t*)(fp+10)) = _mm256_extract_epi16(tmp0,1); + *((uint32_t*)(fp+12)) = _mm256_extract_epi32(tmp0b,2); + *((uint16_t*)(fp+16)) = _mm256_extract_epi16(tmp0,2); + *((uint32_t*)(fp+18)) = _mm256_extract_epi32(tmp0b,3); + *((uint16_t*)(fp+22)) = _mm256_extract_epi16(tmp0,3); + *((uint32_t*)(fp+24)) = _mm256_extract_epi32(tmp0b,4); + *((uint16_t*)(fp+26)) = _mm256_extract_epi16(tmp0,4); + *((uint32_t*)(fp+30)) = _mm256_extract_epi32(tmp0b,5); + *((uint16_t*)(fp+34)) = _mm256_extract_epi16(tmp0,5); + *((uint32_t*)(fp+36)) = _mm256_extract_epi32(tmp0,6); + *((uint16_t*)(fp+40)) = _mm256_extract_epi16(tmp0,6); + *((uint32_t*)(fp+42)) = _mm256_extract_epi32(tmp0b,7); + *((uint16_t*)(fp+46)) = _mm256_extract_epi16(tmp0,7); + + *((uint32_t*)(fp+48)) = _mm256_extract_epi32(tmp1b,0); + *((uint16_t*)(fp+52)) = _mm256_extract_epi16(tmp0,8); + *((uint32_t*)(fp+56)) = _mm256_extract_epi32(tmp1b,1); + *((uint16_t*)(fp+60)) = _mm256_extract_epi16(tmp0,9); + *((uint32_t*)(fp+62)) = _mm256_extract_epi32(tmp1b,2); + *((uint16_t*)(fp+66)) = _mm256_extract_epi16(tmp0,10); + *((uint32_t*)(fp+68)) = _mm256_extract_epi32(tmp1b,3); + *((uint16_t*)(fp+72)) = _mm256_extract_epi16(tmp0,11); + *((uint32_t*)(fp+74)) = _mm256_extract_epi32(tmp1b,4); + *((uint16_t*)(fp+76)) = _mm256_extract_epi16(tmp0,12); + *((uint32_t*)(fp+80)) = _mm256_extract_epi32(tmp1b,5); + *((uint16_t*)(fp+82)) = _mm256_extract_epi16(tmp0,13); + *((uint32_t*)(fp+86)) = _mm256_extract_epi32(tmp1b,6); + *((uint16_t*)(fp+90)) = _mm256_extract_epi16(tmp0,14); + *((uint32_t*)(fp+92)) = _mm256_extract_epi32(tmp1b,7); + *((uint16_t*)(fp+94)) = _mm256_extract_epi16(tmp0,15); + + tmp0 = _mm256_unpackhi_epi8(e0_256[j],e1_256[j]); // e0(i+16) e1(i+16) e0(i+17) e1(i+17) .... e0(i+31) e1(i+31) + tmp1 = _mm256_unpackhi_epi8(e2_256[j],e3_256[j]); // e2(i+16) e3(i+16) e2(i+17) e3(i+17) .... e2(i+31) e3(i+31) + tmp0b = _mm256_unpacklo_epi16(tmp0,tmp1); // e0(i+16) e1(i+16) e2(i+16) e3(i+16) ... e0(i+23) e1(i+23) e2(i+23) e3(i+23) + tmp1b = _mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+24) e1(i+24) e2(i+24) e3(i+24) ... e0(i+31) e1(i+31) e2(i+31) e3(i+31) + tmp0 = _mm256_unpackhi_epi8(e4_256[j],e5_256[j]); // e4(i+16) e5(i+16) e4(i+17) e5(i+17) .... e4(i+31) e5(i+31) + *((uint32_t*)fp2) = _mm256_extract_epi32(tmp0b,0); + *((uint16_t*)(fp2+4)) = _mm256_extract_epi16(tmp0,0); + *((uint32_t*)(fp2+6)) = _mm256_extract_epi32(tmp0b,1); + *((uint16_t*)(fp2+10)) = _mm256_extract_epi16(tmp0,1); + *((uint32_t*)(fp2+12)) = _mm256_extract_epi32(tmp0b,2); + *((uint16_t*)(fp2+16)) = _mm256_extract_epi16(tmp0,2); + *((uint32_t*)(fp2+18)) = _mm256_extract_epi32(tmp0b,3); + *((uint16_t*)(fp2+22)) = _mm256_extract_epi16(tmp0,3); + *((uint32_t*)(fp2+24)) = _mm256_extract_epi32(tmp0b,4); + *((uint16_t*)(fp2+26)) = _mm256_extract_epi16(tmp0,4); + *((uint32_t*)(fp2+30)) = _mm256_extract_epi32(tmp0b,5); + *((uint16_t*)(fp2+34)) = _mm256_extract_epi16(tmp0,5); + *((uint32_t*)(fp2+36)) = _mm256_extract_epi32(tmp0,6); + *((uint16_t*)(fp2+40)) = _mm256_extract_epi16(tmp0,6); + *((uint32_t*)(fp2+42)) = _mm256_extract_epi32(tmp0b,7); + *((uint16_t*)(fp2+46)) = _mm256_extract_epi16(tmp0,7); + + *((uint32_t*)(fp2+48)) = _mm256_extract_epi32(tmp1b,0); + *((uint16_t*)(fp2+52)) = _mm256_extract_epi16(tmp0,8); + *((uint32_t*)(fp2+56)) = _mm256_extract_epi32(tmp1b,1); + *((uint16_t*)(fp2+60)) = _mm256_extract_epi16(tmp0,9); + *((uint32_t*)(fp2+62)) = _mm256_extract_epi32(tmp1b,2); + *((uint16_t*)(fp2+66)) = _mm256_extract_epi16(tmp0,10); + *((uint32_t*)(fp2+68)) = _mm256_extract_epi32(tmp1b,3); + *((uint16_t*)(fp2+72)) = _mm256_extract_epi16(tmp0,11); + *((uint32_t*)(fp2+74)) = _mm256_extract_epi32(tmp1b,4); + *((uint16_t*)(fp2+76)) = _mm256_extract_epi16(tmp0,12); + *((uint32_t*)(fp2+80)) = _mm256_extract_epi32(tmp1b,5); + *((uint16_t*)(fp2+82)) = _mm256_extract_epi16(tmp0,13); + *((uint32_t*)(fp2+86)) = _mm256_extract_epi32(tmp1b,6); + *((uint16_t*)(fp2+90)) = _mm256_extract_epi16(tmp0,14); + *((uint32_t*)(fp2+92)) = _mm256_extract_epi32(tmp1b,7); + *((uint16_t*)(fp2+94)) = _mm256_extract_epi16(tmp0,15); + } + break; + case 8: + e0=e; + e1=e0+EQm; + e2=e1+EQm; + e3=e2+EQm; + e4=e3+EQm; + e5=e4+EQm; + e6=e5+EQm; + e7=e6+EQm; + + e0_256=(__m256i *)e0; + e1_256=(__m256i *)e1; + e2_256=(__m256i *)e2; + e3_256=(__m256i *)e3; + e4_256=(__m256i *)e4; + e5_256=(__m256i *)e5; + e6_256=(__m256i *)e6; + e7_256=(__m256i *)e7; + for (int k=0,j=0;j >5;j++,k+=8) { + tmp0 = _mm256_unpacklo_epi8(e0_256[j],e1_256[j]); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15) + tmp1 = _mm256_unpacklo_epi8(e2_256[j],e3_256[j]); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15) + tmp2 = _mm256_unpacklo_epi8(e4_256[j],e5_256[j]); // e4(i) e5(i) e4(i+1) e5(i+1) .... e4(i+15) e5(i+15) + tmp3 = _mm256_unpacklo_epi8(e6_256[j],e7_256[j]); // e6(i) e7(i) e6(i+1) e7(i+1) .... e6(i+15) e7(i+15) + tmp4 = _mm256_unpacklo_epi16(tmp0,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7) + tmp5 = _mm256_unpacklo_epi16(tmp2,tmp3); // e4(i) e5(i) e6(i) e7(i) ... e4(i+7) e5(i+7) e6(i+7) e7(i+7) + f_256[k] = _mm256_unpacklo_epi16(tmp4,tmp5); // e0(i) e1(i) e2(i) e3(i) e4(i) e5(i) e6(i) e7(i)... e0(i+3) e1(i+3) e2(i+3) e3(i+3) e4(i+3) e5(i+3) e6(i+3) e7(i+3)) + f_256[k+1] = _mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+4) e1(i+4) e2(i+4) e3(i+4) e4(i+4) e5(i+4) e6(i+4) e7(i+4)... e0(i+7) e1(i+7) e2(i+7) e3(i+7) e4(i+7) e5(i+7) e6(i+7) e7(i+7)) + + tmp4 = _mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15) + tmp5 = _mm256_unpackhi_epi16(tmp2,tmp3); // e4(i+8) e5(i+8) e6(i+8) e7(i+8) ... e4(i+15) e5(i+15) e6(i+15) e7(i+15) + f_256[k+2] = _mm256_unpacklo_epi16(tmp4,tmp5); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) e4(i+8) e5(i+8) e6(i+8) e7(i+8)... e0(i+11) e1(i+11) e2(i+11) e3(i+11) e4(i+11) e5(i+11) e6(i+11) e7(i+11)) + f_256[k+3] = _mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+12) e1(i+12) e2(i+12) e3(i+12) e4(i+12) e5(i+12) e6(i+12) e7(i+12)... e0(i+15) e1(i+15) e2(i+15) e3(i+15) e4(i+15) e5(i+15) e6(i+15) e7(i+15)) + + tmp0 = _mm256_unpackhi_epi8(e0_256[j],e1_256[j]); // e0(i+16) e1(i+16) e0(i+17) e1(i+17) .... e0(i+31) e1(i+31) + tmp1 = _mm256_unpackhi_epi8(e2_256[j],e3_256[j]); // e2(i+16) e3(i+16) e2(i+17) e3(i+17) .... e2(i+31) e3(i+31) + tmp2 = _mm256_unpackhi_epi8(e4_256[j],e5_256[j]); // e4(i+16) e5(i+16) e4(i+17) e5(i+17) .... e4(i+31) e5(i+31) + tmp3 = _mm256_unpackhi_epi8(e6_256[j],e7_256[j]); // e6(i+16) e7(i+16) e6(i+17) e7(i+17) .... e6(i+31) e7(i+31) + tmp4 = _mm256_unpacklo_epi16(tmp0,tmp1); // e0(i+!6) e1(i+16) e2(i+16) e3(i+16) ... e0(i+23) e1(i+23) e2(i+23) e3(i+23) + tmp5 = _mm256_unpacklo_epi16(tmp2,tmp3); // e4(i+16) e5(i+16) e6(i+16) e7(i+16) ... e4(i+23) e5(i+23) e6(i+23) e7(i+23) + f_256[k+4] = _mm256_unpacklo_epi16(tmp4,tmp5); // e0(i+16) e1(i+16) e2(i+16) e3(i+16) e4(i+16) e5(i+16) e6(i+16) e7(i+16)... e0(i+19) e1(i+19) e2(i+19) e3(i+19) e4(i+19) e5(i+19) e6(i+19) e7(i+19)) + f_256[k+5] = _mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+20) e1(i+20) e2(i+20) e3(i+20) e4(i+20) e5(i+20) e6(i+20) e7(i+20)... e0(i+23) e1(i+23) e2(i+23) e3(i+23) e4(i+23) e5(i+23) e6(i+23) e7(i+23)) + + tmp4 = _mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+24) e1(i+24) e2(i+24) e3(i+24) ... e0(i+31) e1(i+31) e2(i+31) e3(i+31) + tmp5 = _mm256_unpackhi_epi16(tmp2,tmp3); // e4(i+24) e5(i+24) e6(i+24) e7(i+24) ... e4(i+31) e5(i+31) e6(i+31) e7(i+31) + f_256[k+6] = _mm256_unpacklo_epi16(tmp4,tmp5); // e0(i+24) e1(i+24) e2(i+24) e3(i+24) e4(i+24) e5(i+24) e6(i+24) e7(i+24)... e0(i+27) e1(i+27) e2(i+27) e3(i+27) e4(i+27) e5(i+27) e6(i+27) e7(i+27)) + f_256[k+7] = _mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+28) e1(i+28) e2(i+28) e3(i+28) e4(i+28) e5(i+28) e6(i+28) e7(i+28)... e0(i+31) e1(i+31) e2(i+31) e3(i+31) e4(i+31) e5(i+31) e6(i+31) e7(i+31)) + } + break; + default: AssertFatal(1==0,"Should be here!\n"); } +#else + //original unoptimized loops + /* + for (int j = 0; j< EQm; j++,j2+=2){ + for (int i = 0; i< Qm; i++){ + f[(i+j*Qm)] = e[(i*EQm + j)]; + } + } + */ + + int j2=0; + fp=f; + switch (Qm) { + case 2: + e0=e; + e1=e0+EQm; + for (int j = 0; j< EQm; j++,j2+=2){ + fp=&f[j2]; + fp[0] = e0[j]; + fp[1] = e1[j]; + } + break; + case 4: + e0=e; + e1=e0+EQm; + e2=e1+EQm; + e3=e2+EQm; + for (int j = 0; j< EQm; j++,j2+=4){ + fp=&f[j2]; + fp[0] = e0[j]; + fp[1] = e1[j]; + fp[2] = e2[j]; + fp[3] = e3[j]; + } + break; + case 6: + e0=e; + e1=e0+EQm; + e2=e1+EQm; + e3=e2+EQm; + e4=e3+EQm; + e5=e4+EQm; + fp = f; + for (int j = 0; j< EQm; j++){ + *fp++ = e0[j]; + *fp++ = e1[j]; + *fp++ = e2[j]; + *fp++ = e3[j]; + *fp++ = e4[j]; + *fp++ = e5[j]; + } + break; + case 8: + e0=e; + e1=e0+EQm; + e2=e1+EQm; + e3=e2+EQm; + e4=e3+EQm; + e5=e4+EQm; + e6=e5+EQm; + e7=e6+EQm; + for (int j = 0; j< EQm; j++,j2+=8){ + fp=&f[j2]; + fp[0] = e0[j]; + fp[1] = e1[j]; + fp[2] = e2[j]; + fp[3] = e3[j]; + fp[4] = e4[j]; + fp[5] = e5[j]; + fp[6] = e6[j]; + fp[7] = e7[j]; + } + break; + default: AssertFatal(1==0,"Should never be here!\n"); + } +#endif } + + void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f) { @@ -71,6 +329,8 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm, uint8_t *w, uint8_t *e, uint8_t C, + uint32_t F, + uint32_t Foffset, uint8_t rvidx, uint32_t E) { @@ -94,21 +354,36 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm, ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z; #ifdef RM_DEBUG - printf("nr_rate_matching_ldpc: E %d, k0 %d, Ncb %d, rvidx %d\n", E, ind, Ncb, rvidx); + printf("nr_rate_matching_ldpc: E %d, F %d, Foffset %d, k0 %d, Ncb %d, rvidx %d\n", E, F, Foffset,ind, Ncb, rvidx); #endif + AssertFatal(Foffset <= E,"Foffset %d > E %d\n",Foffset,E); + AssertFatal(Foffset <= Ncb,"Foffset %d > Ncb %d\n",Foffset,Ncb); - k=0; + if (ind >= Foffset && ind < (F+Foffset)) ind = F+Foffset; - for (; (ind E %d\n",Foffset,E); + AssertFatal(Foffset <= Ncb,"Foffset %d > Ncb %d\n",Foffset,Ncb); #ifdef RM_DEBUG printf("nr_rate_matching_ldpc_rx: Clear %d, E %d, k0 %d, Ncb %d, rvidx %d\n", clear, E, ind, Ncb, rvidx); #endif - if (clear==1) - memset(w,0,Ncb*sizeof(int16_t)); + if (clear==1) memset(w,0,Ncb*sizeof(int16_t)); k=0; + if (ind < Foffset) + for (; (ind ",k,ind,w[ind],soft_input[k]); +#endif + w[ind]+=soft_input[k++]; +#ifdef RM_DEBUG + printf("%d\n",w[ind]); +#endif + } + if (ind >= Foffset && ind < Foffset+F) ind=Foffset+F; + for (; (ind ",k,ind,w[ind],soft_input[k]); +#endif w[ind] += soft_input[k++]; #ifdef RM_DEBUG - printf("RM_RX k%d Ind: %d (%d)\n",k-1,ind,w[ind]); -#endif - } - -#ifdef RM_DEBUG - else { - printf("RM_RX Ind: %d NULL %d\n",ind,nulled); - nulled++; - } - + printf("%d\n",w[ind]); #endif } - if (rvidx !=0){ while(k ",k,ind,w[ind],soft_input[k]); #endif - } - + w[ind]+=soft_input[k++]; #ifdef RM_DEBUG - else { - printf("RM_RX Ind: %d NULL %d\n",ind,nulled); - nulled++; - } - + printf("%d\n",w[ind]); +#endif + } + for (ind=Foffset+F; (ind ",k,ind,w[ind],soft_input[k]); +#endif + w[ind] += soft_input[k++]; +#ifdef RM_DEBUG + printf("%d\n",w[ind]); #endif } } - } + return 0; } + diff --git a/openair1/PHY/CODING/nr_segmentation.c b/openair1/PHY/CODING/nr_segmentation.c index 421f440ec2..462cdee1fc 100644 --- a/openair1/PHY/CODING/nr_segmentation.c +++ b/openair1/PHY/CODING/nr_segmentation.c @@ -35,55 +35,65 @@ int32_t nr_segmentation(unsigned char *input_buffer, unsigned int *C, unsigned int *K, unsigned int *Zout, // [hna] Zout is Zc - unsigned int *F) + unsigned int *F, + uint8_t BG) { - unsigned int L,Bprime,Bprime_by_C,Z,r,Kb,k,s,crc,Kprime; + unsigned int L,Bprime,Z,r,Kcb,Kb,k,s,crc,Kprime; - if (B<=8448) { + if (BG==1) + Kcb=8448; + else + Kcb=3840; + + if (B<=Kcb) { L=0; *C=1; Bprime=B; } else { L=24; - *C = B/(8448-L); + *C = B/(Kcb-L); - if ((8448-L)*(*C) < B) + if ((Kcb-L)*(*C) < B) *C=*C+1; Bprime = B+((*C)*L); #ifdef DEBUG_SEGMENTATION - printf("Bprime %d\n",Bprime); + printf("Bprime %u\n",Bprime); #endif } - if ((*C)>MAX_NUM_DLSCH_SEGMENTS) { - LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime); + if ((*C)>MAX_NUM_NR_DLSCH_SEGMENTS) { + LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime); return(-1); } // Find K+ - Bprime_by_C = Bprime/(*C); - if (Bprime <=192) { - Kb = 6; - } else if (Bprime <=560) { - Kb = 8; - } else if (Bprime <=640) { - Kb = 9; - } else if (Bprime <=3840) { - Kb = 10;; - } else { - Kb = 22; + Kprime = Bprime/(*C); + + if (BG==1) + Kb = 22; + else { + if (B > 640) { + Kb = 10; + } else if (B > 560) { + Kb = 9; + } else if (B > 192) { + Kb = 8; + } + else { + Kb = 6; + } } -if ((Bprime_by_C%Kb) > 0) - Z = (Bprime_by_C/Kb)+1; +if ((Kprime%Kb) > 0) + Z = (Kprime/Kb)+1; else - Z = (Bprime_by_C/Kb); + Z = (Kprime/Kb); #ifdef DEBUG_SEGMENTATION - printf("nr segmetation B %d Bprime %d Bprime_by_C %d z %d \n", B, Bprime, Bprime_by_C, Z); + printf("nr segmetation B %u Bprime %u Kprime %u z %u \n", B, Bprime, Kprime, Z); #endif if (Z <= 2) { @@ -110,7 +120,7 @@ else *K = *K + 8; #ifdef DEBUG_SEGMENTATION - printf("Z_by_C %d , K2 %d\n",Z,*K); + printf("Z_by_C %u , K2 %u\n",Z,*K); #endif } else if (Z <= 256) { // increase by 4 bytes til here *K = (Z>>4)<<4; @@ -128,14 +138,19 @@ else //msg("nr_segmentation.c: Illegal codeword size !!!\n"); return -1; } - *Zout = *K; - *K = *K*Kb; - *F = ((*K) - Bprime_by_C); + *Zout = *K; + + if(BG==1) + *K = *K*22; + else + *K = *K*10; + + *F = ((*K) - Kprime); #ifdef DEBUG_SEGMENTATION - printf("final nr seg output Z %d K %d F %d \n", *Zout, *K, *F); - printf("C %d, K %d, Bprime_bytes %d, Bprime %d, F %d\n",*C,*K,Bprime>>3,Bprime,*F); + printf("final nr seg output Z %u K %u F %u \n", *Zout, *K, *F); + printf("C %u, K %u, Bprime_bytes %u, Bprime %u, F %u\n",*C,*K,Bprime>>3,Bprime,*F); #endif if ((input_buffer) && (output_buffers)) { @@ -145,7 +160,6 @@ else for (r=0; r<*C; r++) { k = 0; - Kprime = Bprime_by_C; while (k<((Kprime - L)>>3)) { output_buffers[r][k] = input_buffer[s]; @@ -154,6 +168,13 @@ else s++; } + if (*C > 1) { // add CRC + crc = crc24b(output_buffers[r],Kprime-L)>>8; + output_buffers[r][(Kprime-L)>>3] = ((uint8_t*)&crc)[2]; + output_buffers[r][1+((Kprime-L)>>3)] = ((uint8_t*)&crc)[1]; + output_buffers[r][2+((Kprime-L)>>3)] = ((uint8_t*)&crc)[0]; + } + if (*F>0) { for (k=Kprime>>3; k<(*K)>>3; k++) { output_buffers[r][k] = 0; @@ -161,16 +182,10 @@ else } } - if (*C > 1) { // add CRC - crc = crc24b(output_buffers[r],Kprime-L)>>8; - output_buffers[r][(Kprime-L)>>3] = ((uint8_t*)&crc)[2]; - output_buffers[r][1+((Kprime-L)>>3)] = ((uint8_t*)&crc)[1]; - output_buffers[r][2+((Kprime-L)>>3)] = ((uint8_t*)&crc)[0]; - } } } - return 0; + return Kb; } diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index d5b5065c9b..2c84af188e 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -19,6 +19,7 @@ * contact@openairinterface.org */ +#include "executables/nr-softmodem-common.h" #include "PHY/defs_gNB.h" #include "PHY/phy_extern.h" #include "PHY/NR_REFSIG/nr_refsig.h" @@ -30,7 +31,7 @@ #include "TDD-Config.h" #include "MBSFN-SubframeConfigList.h"*/ #include "openair1/PHY/defs_RU.h" -#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "assertions.h" #include @@ -38,6 +39,7 @@ #include "PHY/NR_REFSIG/nr_refsig.h" #include "SCHED_NR/fapi_nr_l1.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" +#include "nfapi_nr_interface.h" /* extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn); @@ -76,7 +78,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char abstraction_flag) { // shortcuts NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms; - nfapi_nr_config_request_t *cfg = &gNB->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; NR_gNB_COMMON *const common_vars = &gNB->common_vars; NR_gNB_PRACH *const prach_vars = &gNB->prach_vars; NR_gNB_PUSCH **const pusch_vars = gNB->pusch_vars; @@ -84,12 +86,12 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/ int i; + int Ptx=cfg->carrier_config.num_tx_ant.value; + int Prx=cfg->carrier_config.num_rx_ant.value; + AssertFatal(Ptx>0 && Ptx<9,"Ptx %d is not supported\n",Ptx); + AssertFatal(Prx>0 && Prx<9,"Prx %d is not supported\n",Prx); LOG_I(PHY,"[gNB %d] %s() About to wait for gNB to be configured\n", gNB->Mod_id, __FUNCTION__); - gNB->total_dlsch_bitrate = 0; - gNB->total_transmitted_bits = 0; - gNB->total_system_throughput = 0; - gNB->check_for_MUMIMO_transmissions=0; while(gNB->configured == 0) usleep(10000); @@ -127,7 +129,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, } } - nr_init_pdcch_dmrs(gNB, cfg->sch_config.physical_cell_id.value); + nr_init_pdcch_dmrs(gNB, cfg->cell_config.phy_cell_id.value); nr_init_pbch_interleaver(gNB->nr_pbch_interleaver); //PDSCH DMRS init gNB->nr_gold_pdsch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***)); @@ -148,26 +150,29 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, } } - nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value); + nr_init_pdsch_dmrs(gNB, cfg->cell_config.phy_cell_id.value); /// Transport init necessary for NR synchro init_nr_transport(gNB); - gNB->first_run_I0_measurements = - 1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here. - common_vars->rxdata = (int32_t **)malloc16(15*sizeof(int32_t*)); - common_vars->txdataF = (int32_t **)malloc16(15*sizeof(int32_t*)); - common_vars->rxdataF = (int32_t **)malloc16(15*sizeof(int32_t*)); + gNB->first_run_I0_measurements = 1; - for (i=0;i<15;i++){ + common_vars->rxdata = (int32_t **)malloc16(Prx*sizeof(int32_t*)); + common_vars->txdataF = (int32_t **)malloc16(Ptx*sizeof(int32_t*)); + common_vars->rxdataF = (int32_t **)malloc16(Prx*sizeof(int32_t*)); + + for (i=0;i txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP - common_vars->rxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); - common_vars->rxdata[i] = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)); - LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n", - i,common_vars->txdataF[i], - fp->samples_per_frame_wCP*sizeof(int32_t)); + i,common_vars->txdataF[i], + fp->samples_per_frame_wCP*sizeof(int32_t)); + } + for (i=0;i rxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); + common_vars->rxdata[i] = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)); + } + // Channel estimates for SRS /* @@ -196,95 +201,61 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, prach_vars->rxsigF = (int16_t *)malloc16_clear( 1024*2*sizeof(int16_t) ); prach_vars->prach_ifft = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t)); + int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value; - for (int ulsch_id=0; ulsch_id dlsch[0][0]->harq_processes[0]); + for (int ULSCH_id=0; ULSCH_id dlsch[0][0]->harq_processes[0]); + pusch_vars[ULSCH_id] = (NR_gNB_PUSCH *)malloc16_clear( sizeof(NR_gNB_PUSCH) ); + pusch_vars[ULSCH_id]->rxdataF_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->rxdataF_ext2 = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_estimates = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_estimates_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_estimates_time = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->rxdataF_comp = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_mag0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_magb0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_mag = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_magb = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->rho = (int32_t **)malloc16_clear(Prx*sizeof(int32_t*) ); - //FIXME - pusch_vars[ulsch_id] = (NR_gNB_PUSCH *)malloc16_clear( sizeof(NR_gNB_PUSCH) ); - pusch_vars[ulsch_id]->rxdataF_ext = (int32_t **)malloc16( 2*sizeof(int32_t *) ); - pusch_vars[ulsch_id]->rxdataF_ext2 = (int32_t **)malloc16( 2*sizeof(int32_t *) ); - pusch_vars[ulsch_id]->drs_ch_estimates = (int32_t **)malloc16( 2*sizeof(int32_t *) ); - pusch_vars[ulsch_id]->drs_ch_estimates_time = (int32_t **)malloc16( 2*sizeof(int32_t *) ); - pusch_vars[ulsch_id]->rxdataF_comp = (int32_t **)malloc16( 2*sizeof(int32_t *) ); - pusch_vars[ulsch_id]->ul_ch_mag = (int32_t **)malloc16( 2*sizeof(int32_t *) ); - pusch_vars[ulsch_id]->ul_ch_magb = (int32_t **)malloc16( 2*sizeof(int32_t *) ); - - for (i=0; i<2; i++) { - // RK 2 times because of output format of FFT! - // FIXME We should get rid of this - pusch_vars[ulsch_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); - pusch_vars[ulsch_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); - pusch_vars[ulsch_id]->drs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); - pusch_vars[ulsch_id]->drs_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size ); - pusch_vars[ulsch_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); - pusch_vars[ulsch_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 ); - pusch_vars[ulsch_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 ); + printf("ULSCH_id %d (before rx antenna alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]); + for (i=0; i rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->ul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size ); + pusch_vars[ULSCH_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot ); + pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); + pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); + pusch_vars[ULSCH_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); + pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); + pusch_vars[ULSCH_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) ); } - - pusch_vars[ulsch_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear + printf("ULSCH_id %d (before llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]); + pusch_vars[ULSCH_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear + printf("ULSCH_id %d (after llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]); } //ulsch_id /* for (ulsch_id=0; ulsch_id UE_stats_ptr[ulsch_id] = &gNB->UE_stats[ulsch_id]; */ - gNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration + printf("After ULSCH init : %p\n",gNB->dlsch[0][0]->harq_processes[0]); return (0); } -/* -void phy_config_request(PHY_Config_t *phy_config) { - - uint8_t Mod_id = phy_config->Mod_id; - int CC_id = phy_config->CC_id; - nfapi_nr_config_request_t *cfg = phy_config->cfg; - - NR_DL_FRAME_PARMS *fp; - PHICH_RESOURCE_t phich_resource_table[4]={oneSixth,half,one,two}; - int eutra_band = cfg->nfapi_config.rf_bands.rf_band[0]; - int dl_Bandwidth = cfg->rf_config.dl_carrier_bandwidth.value; - int ul_Bandwidth = cfg->rf_config.ul_carrier_bandwidth.value; - int Nid_cell = cfg->sch_config.physical_cell_id.value; - int Ncp = cfg->subframe_config.dl_cyclic_prefix_type.value; - int p_eNB = cfg->rf_config.tx_antenna_ports.value; - uint32_t dl_CarrierFreq = cfg->nfapi_config.earfcn.value; - - LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,gNB_tx_antenna_ports %d,Ncp %d,DL freq %u)\n", - Mod_id, CC_id, eutra_band, dl_Bandwidth, ul_Bandwidth, Nid_cell, p_eNB,Ncp,dl_CarrierFreq ); - - AssertFatal(RC.gNB != NULL, "PHY instance pointer doesn't exist\n"); - AssertFatal(RC.gNB[Mod_id] != NULL, "PHY instance %d doesn't exist\n",Mod_id); - AssertFatal(RC.gNB[Mod_id][CC_id] != NULL, "PHY instance %d, CCid %d doesn't exist\n",Mod_id,CC_id); - - - if (RC.gNB[Mod_id][CC_id]->configured == 1) - { - LOG_E(PHY,"Already eNB already configured, do nothing\n"); - return; - } - - RC.gNB[Mod_id][CC_id]->mac_enabled = 1; - - fp = &RC.gNB[Mod_id][CC_id]->frame_parms; - - fp->threequarter_fs = 0; - - nr_init_frame_parms(fp,1); - - RC.gNB[Mod_id][CC_id]->configured = 1; - LOG_I(PHY,"gNB %d/%d configured\n",Mod_id,CC_id); -}*/ - void phy_free_nr_gNB(PHY_VARS_gNB *gNB) { //NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms; - //nfapi_nr_config_request_t *cfg = &gNB->gNB_config; NR_gNB_COMMON *const common_vars = &gNB->common_vars; - //NR_gNB_PUSCH **const pusch_vars = gNB->pusch_vars; + NR_gNB_PUSCH **const pusch_vars = gNB->pusch_vars; /*LTE_eNB_SRS *const srs_vars = gNB->srs_vars; LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/ uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs; + int Ptx=gNB->gNB_config.carrier_config.num_tx_ant.value; - for (int i = 0; i < 15; i++) { + for (int i = 0; i < Ptx; i++) { free_and_zero(common_vars->txdataF[i]); /* rxdataF[i] is not allocated -> don't free */ } @@ -315,29 +286,38 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(prach_vars->prach_ifft[0]); free_and_zero(prach_vars->rxsigF[0]); - - for (UE_id=0; UE_id rxdataF_ext[i]); - free_and_zero(pusch_vars[UE_id]->rxdataF_ext2[i]); - free_and_zero(pusch_vars[UE_id]->drs_ch_estimates[i]); - free_and_zero(pusch_vars[UE_id]->drs_ch_estimates_time[i]); - free_and_zero(pusch_vars[UE_id]->rxdataF_comp[i]); - free_and_zero(pusch_vars[UE_id]->ul_ch_mag[i]); - free_and_zero(pusch_vars[UE_id]->ul_ch_magb[i]); +*/ + for (int ULSCH_id=0; ULSCH_id rxdataF_ext[i]); + free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2[i]); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates[i]); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i]); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time[i]); + free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp[i]); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0[i]); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb0[i]); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag[i]); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb[i]); + free_and_zero(pusch_vars[ULSCH_id]->rho[i]); } - free_and_zero(pusch_vars[UE_id]->rxdataF_ext); - free_and_zero(pusch_vars[UE_id]->rxdataF_ext2); - free_and_zero(pusch_vars[UE_id]->drs_ch_estimates); - free_and_zero(pusch_vars[UE_id]->drs_ch_estimates_time); - free_and_zero(pusch_vars[UE_id]->rxdataF_comp); - free_and_zero(pusch_vars[UE_id]->ul_ch_mag); - free_and_zero(pusch_vars[UE_id]->ul_ch_magb); - free_and_zero(pusch_vars[UE_id]->llr); - free_and_zero(pusch_vars[UE_id]); - } //UE_id + free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext); + free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_ext); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time); + free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb0); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb); + free_and_zero(pusch_vars[ULSCH_id]->rho); + free_and_zero(pusch_vars[ULSCH_id]->llr); + free_and_zero(pusch_vars[ULSCH_id]); + } //ULSCH_id +/* for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) gNB->UE_stats_ptr[UE_id] = NULL; */ } @@ -359,25 +339,28 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, uint64_t position_in_burst) { NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - nfapi_nr_config_request_t *gNB_config = &gNB->gNB_config; + nfapi_nr_config_request_scf_t *gNB_config = &gNB->gNB_config; //overwrite for new NR parameters - gNB_config->nfapi_config.rf_bands.rf_band[0] = 78; - gNB_config->nfapi_config.nrarfcn.value = 620000; - gNB_config->subframe_config.numerology_index_mu.value = mu; - gNB_config->subframe_config.duplex_mode.value = TDD; - gNB_config->rf_config.dl_carrier_bandwidth.value = N_RB_DL; - gNB_config->rf_config.ul_carrier_bandwidth.value = N_RB_UL; - gNB_config->sch_config.half_frame_index.value = 0; - gNB_config->sch_config.ssb_subcarrier_offset.value = 0; - gNB_config->sch_config.n_ssb_crb.value = (N_RB_DL-20); - gNB_config->sch_config.ssb_subcarrier_offset.value = 0; - gNB_config->sch_config.physical_cell_id.value = Nid_cell; - gNB_config->sch_config.ssb_scg_position_in_burst.value = position_in_burst; - gNB_config->subframe_config.dl_cyclic_prefix_type.value = (fp->Ncp == NORMAL) ? NFAPI_CP_NORMAL : NFAPI_CP_EXTENDED; + + gNB_config->cell_config.phy_cell_id.value = Nid_cell; + gNB_config->ssb_config.scs_common.value = mu; + gNB_config->ssb_table.ssb_subcarrier_offset.value = 0; + gNB_config->ssb_table.ssb_offset_point_a.value = (N_RB_DL-20)>>1; + gNB_config->ssb_table.ssb_mask_list[0].ssb_mask.value = position_in_burst; + gNB_config->ssb_table.ssb_mask_list[1].ssb_mask.value = position_in_burst>>32; + gNB_config->cell_config.frame_duplex_type.value = TDD; + gNB_config->ssb_table.ssb_period.value = 1; //10ms + gNB_config->carrier_config.dl_grid_size[mu].value = N_RB_DL; + gNB_config->carrier_config.ul_grid_size[mu].value = N_RB_UL; + gNB_config->carrier_config.num_tx_ant.value = fp->nb_antennas_tx; + gNB_config->carrier_config.num_rx_ant.value = fp->nb_antennas_rx; + + //gNB_config->subframe_config.dl_cyclic_prefix_type.value = (fp->Ncp == NORMAL) ? NFAPI_CP_NORMAL : NFAPI_CP_EXTENDED; gNB->mac_enabled = 1; fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); + fp->eutra_band = 78; fp->threequarter_fs= 0; nr_init_frame_parms(gNB_config, fp); gNB->configured = 1; @@ -386,42 +369,59 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, void nr_phy_config_request(NR_PHY_Config_t *phy_config) { - uint8_t Mod_id = phy_config->Mod_id; - NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms; - nfapi_nr_config_request_t *gNB_config = &RC.gNB[Mod_id]->gNB_config; - gNB_config->nfapi_config.rf_bands.rf_band[0] = phy_config->cfg->nfapi_config.rf_bands.rf_band[0]; //22 - gNB_config->nfapi_config.nrarfcn.value = phy_config->cfg->nfapi_config.nrarfcn.value; //6600 - gNB_config->subframe_config.numerology_index_mu.value = phy_config->cfg->subframe_config.numerology_index_mu.value;//1 - gNB_config->rf_config.dl_carrier_bandwidth.value = phy_config->cfg->rf_config.dl_carrier_bandwidth.value;//106; - gNB_config->rf_config.ul_carrier_bandwidth.value = phy_config->cfg->rf_config.ul_carrier_bandwidth.value;//106; - gNB_config->sch_config.half_frame_index.value = 0; - gNB_config->sch_config.ssb_subcarrier_offset.value = phy_config->cfg->sch_config.ssb_subcarrier_offset.value;//0; - gNB_config->sch_config.n_ssb_crb.value = (phy_config->cfg->rf_config.dl_carrier_bandwidth.value-20); - gNB_config->sch_config.physical_cell_id.value = phy_config->cfg->sch_config.physical_cell_id.value; - gNB_config->sch_config.ssb_scg_position_in_burst.value= phy_config->cfg->sch_config.ssb_scg_position_in_burst.value; - gNB_config->sch_config.ssb_periodicity.value = phy_config->cfg->sch_config.ssb_periodicity.value; + uint8_t Mod_id = phy_config->Mod_id; + NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms; + nfapi_nr_config_request_scf_t *gNB_config = &RC.gNB[Mod_id]->gNB_config; - if (phy_config->cfg->subframe_config.duplex_mode.value == 0) { - gNB_config->subframe_config.duplex_mode.value = TDD; - } else { - gNB_config->subframe_config.duplex_mode.value = FDD; + /* + gNB_config->cell_config.phy_cell_id.value = phy_config->cfg->cell_config.phy_cell_id.value; + gNB_config->carrier_config.dl_frequency.value = phy_config->cfg->carrier_config.dl_frequency.value; + gNB_config->carrier_config.uplink_frequency.value = phy_config->cfg->carrier_config.uplink_frequency.value; + gNB_config->ssb_config.scs_common.value = phy_config->cfg->ssb_config.scs_common.value; + gNB_config->carrier_config.dl_bandwidth.value = phy_config->cfg->carrier_config.dl_bandwidth.value; + gNB_config->carrier_config.uplink_bandwidth.value = phy_config->cfg->carrier_config.uplink_bandwidth.value; + gNB_config->ssb_table.ssb_subcarrier_offset.value = phy_config->cfg->ssb_table.ssb_subcarrier_offset.value; + gNB_config->ssb_table.ssb_offset_point_a.value = phy_config->cfg->ssb_table.ssb_offset_point_a.value; + gNB_config->ssb_table.ssb_mask_list[0].ssb_mask.value = phy_config->cfg->ssb_table.ssb_mask_list[0].ssb_mask.value; + gNB_config->ssb_table.ssb_mask_list[1].ssb_mask.value = phy_config->cfg->ssb_table.ssb_mask_list[1].ssb_mask.value; + gNB_config->ssb_table.ssb_period.value = phy_config->cfg->ssb_table.ssb_period.value; + for (int i=0; i<5; i++) { + gNB_config->carrier_config.dl_grid_size[i].value = phy_config->cfg->carrier_config.dl_grid_size[i].value; + gNB_config->carrier_config.ul_grid_size[i].value = phy_config->cfg->carrier_config.ul_grid_size[i].value; + gNB_config->carrier_config.dl_k0[i].value = phy_config->cfg->carrier_config.dl_k0[i].value; + gNB_config->carrier_config.ul_k0[i].value = phy_config->cfg->carrier_config.ul_k0[i].value; } - memcpy((void*)&gNB_config->rach_config,(void*)&phy_config->cfg->rach_config,sizeof(phy_config->cfg->rach_config)); + if (phy_config->cfg->cell_config.frame_duplex_type.value == 0) { + gNB_config->cell_config.frame_duplex_type.value = FDD; + } else { + gNB_config->cell_config.frame_duplex_type.value = TDD; + } + + memcpy((void*)&gNB_config->prach_config,(void*)&phy_config->cfg->prach_config,sizeof(phy_config->cfg->prach_config)); + memcpy((void*)&gNB_config->tdd_table,(void*)&phy_config->cfg->tdd_table,sizeof(phy_config->cfg->tdd_table)); + */ + memcpy((void*)gNB_config,phy_config->cfg,sizeof(*phy_config->cfg)); RC.gNB[Mod_id]->mac_enabled = 1; - fp->dl_CarrierFreq = from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); - fp->ul_CarrierFreq = fp->dl_CarrierFreq - (get_nr_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); - LOG_I(PHY,"Configuring MIB for instance %d, : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,DL freq %u)\n", - Mod_id, - gNB_config->nfapi_config.rf_bands.rf_band[0], - gNB_config->rf_config.dl_carrier_bandwidth.value, - gNB_config->rf_config.ul_carrier_bandwidth.value, - gNB_config->sch_config.physical_cell_id.value, - fp->dl_CarrierFreq ); + fp->dl_CarrierFreq = (gNB_config->carrier_config.dl_frequency.value)*1e3 + (gNB_config->carrier_config.dl_bandwidth.value)*5e5; + int32_t dlul_offset = 0; + lte_frame_type_t frame_type = 0; + + get_band(fp->dl_CarrierFreq,&fp->eutra_band,&dlul_offset,&frame_type); + + fp->ul_CarrierFreq = (gNB_config->carrier_config.uplink_frequency.value)*1e3 + (gNB_config->carrier_config.uplink_bandwidth.value)*5e5; + + fp->threequarter_fs = openair0_cfg[0].threequarter_fs; + LOG_I(PHY,"Configuring MIB for instance %d, : (Nid_cell %d,DL freq %llu, UL freq %llu)\n", + Mod_id, + gNB_config->cell_config.phy_cell_id.value, + (unsigned long long)fp->dl_CarrierFreq, + (unsigned long long)fp->ul_CarrierFreq); nr_init_frame_parms(gNB_config, fp); + if (RC.gNB[Mod_id]->configured == 1) { LOG_E(PHY,"Already gNB already configured, do nothing\n"); @@ -436,60 +436,61 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { int i; int j; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - nfapi_nr_config_request_t *cfg = &gNB->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; LOG_I(PHY, "Initialise nr transport\n"); + uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value; for (i=0; i dlsch[i][j] = new_gNB_dlsch(1,16,NSOFT,0,fp,cfg); - - if (!gNB->dlsch[i][j]) { - LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i); - exit(-1); - }/* else { - gNB->dlsch[i][j]->rnti=0; - LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,gNB->dlsch[i][j], gNB->dlsch[i][j]->rnti); - }*/ + gNB->dlsch[i][j] = new_gNB_dlsch(fp,1,16,NSOFT,0,grid_size); + AssertFatal(gNB->dlsch[i][j]!=NULL,"Can't initialize dlsch %d \n", i); } } - for (i=0; i ulsch[i][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0); - - if (!gNB->ulsch[i][j]) { - LOG_E(PHY,"Can't get gNB ulsch structures\n"); - exit(-1); - } - } - // ULSCH for data - gNB->ulsch[i+1][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0); + gNB->ulsch[i][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0); - if (!gNB->ulsch[i+1][j]) { + if (!gNB->ulsch[i][j]) { LOG_E(PHY,"Can't get gNB ulsch structures\n"); exit(-1); } - ////////////////////////////////////////////////////////////////////////// + + /* + LOG_I(PHY,"Initializing nFAPI for ULSCH, UE %d\n",i); + // [hna] added here for RT implementation + uint8_t harq_pid = 0; + nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &gNB->ulsch[i+1][j]->harq_processes[harq_pid]->ulsch_pdu; + + // --------- setting rel15_ul parameters ---------- + rel15_ul->rnti = 0x1234; + rel15_ul->ulsch_pdu_rel15.start_rb = 0; + rel15_ul->ulsch_pdu_rel15.number_rbs = 50; + rel15_ul->ulsch_pdu_rel15.start_symbol = 2; + rel15_ul->ulsch_pdu_rel15.number_symbols = 12; + rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; + rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; + rel15_ul->ulsch_pdu_rel15.Qm = 2; + rel15_ul->ulsch_pdu_rel15.R = 679; + rel15_ul->ulsch_pdu_rel15.mcs = 9; + rel15_ul->ulsch_pdu_rel15.rv = 0; + rel15_ul->ulsch_pdu_rel15.n_layers = 1; + /////////////////////////////////////////////////// + */ + } - // this is the transmission mode for the signalling channels - // this will be overwritten with the real transmission mode by the RRC once the UE is connected - //gNB->transmission_mode[i] = fp->nb_antenna_ports_gNB==1 ? 1 : 2; } gNB->rx_total_gain_dB=130; - for(i=0; i mu_mimo_mode[i].dl_pow_off = 2; //fp->pucch_config_common.deltaPUCCH_Shift = 1; } diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 73305e3586..2dcf035866 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -41,6 +41,13 @@ int nr_phy_init_RU(RU_t *ru) { LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d\n",ru_if_types[ru->if_south],ru->nb_tx); + nfapi_nr_config_request_scf_t *cfg; + ru->nb_log_antennas=0; + for (int n=0;n gNB_config; + if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas) ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value; + } + AssertFatal(ru->nb_log_antennas > 0 && ru->nb_log_antennas < 13, "ru->nb_log_antennas %d ! \n",ru->nb_log_antennas); if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals // Time-domain signals ru->common.txdata = (int32_t**)malloc16(ru->nb_tx*sizeof(int32_t*)); @@ -74,6 +81,10 @@ int nr_phy_init_RU(RU_t *ru) { } + // allocate precoding input buffers (TX) + ru->common.txdataF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*)); + for(i=0; i< ru->nb_tx; ++i) ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP + // allocate IFFT input buffers (TX) ru->common.txdataF_BF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*)); LOG_I(PHY,"[INIT] common.txdata_BF= %p (%lu bytes)\n",ru->common.txdataF_BF, @@ -104,37 +115,33 @@ int nr_phy_init_RU(RU_t *ru) { RC.nb_nr_L1_inst,NUMBER_OF_gNB_MAX); LOG_E(PHY,"[INIT] %s() RC.nb_nr_L1_inst:%d \n", __FUNCTION__, RC.nb_nr_L1_inst); - - for (i=0; i beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); - for (j=0; j nb_tx; j++) { - ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); - // antenna ports 0-3 are mapped on antennas 0-3 - // antenna port 4 is mapped on antenna 0 - // antenna ports 5-14 are mapped on all antennas - if (((p<4) && (p==j)) || ((p==4) && (j==0))) { - for (re=0; re ofdm_symbol_size; re++) - { - ru->beam_weights[i][p][j][re] = 0x00007fff; - - //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); - } - } - else if (p>4) { - for (re=0; re ofdm_symbol_size; re++) - { - ru->beam_weights[i][p][j][re] = 0x00007fff/ru->nb_tx; - //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); - } - } - //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d] = %p (%lu bytes)\n", i,j,ru->beam_weights[i][p][j], fp->ofdm_symbol_size*sizeof(int32_t)); - } // for (j=0 - } // if (p nb_log_antennas>1) { + for (p=0;p nb_log_antennas;p++) { + if ((fp->L_ssb >> p) & 0x01) + beam_count++; + } + AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx)); + + int l_ind = 0; + for (i=0; i nb_log_antennas;p++) { + if ((fp->L_ssb >> p) & 0x01) { + ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); + for (j=0; j nb_tx; j++) { + ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); + for (re=0; re ofdm_symbol_size; re++) + ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind]; + //printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j); + l_ind++; + } // for j + } // for p + } + } //for i + } } // !=IF5 + ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_subframe_wCP ); return(0); @@ -161,6 +168,10 @@ void nr_phy_free_RU(RU_t *ru) for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata_7_5kHz[i]); free_and_zero(ru->common.rxdata_7_5kHz); + // free beamforming input buffers (TX) + for (i = 0; i < 15; i++) free_and_zero(ru->common.txdataF[i]); + free_and_zero(ru->common.txdataF); + // free IFFT input buffers (TX) for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdataF_BF[i]); free_and_zero(ru->common.txdataF_BF); @@ -175,10 +186,8 @@ void nr_phy_free_RU(RU_t *ru) for (i = 0; i < RC.nb_nr_L1_inst; i++) { for (p = 0; p < 15; p++) { - if (p == 0 || p == 5) { for (j=0; j nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]); free_and_zero(ru->beam_weights[i][p]); - } } } } diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index cd0620012f..2a5df46895 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -649,7 +649,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int i,j,k,l,slot,symb,q; int eNB_id; int th_id; - int n_ssb_crb=(fp->N_RB_DL-20); + int n_ssb_crb=(fp->N_RB_DL-20)>>1; int k_ssb=0; uint32_t ****pusch_dmrs; uint16_t N_n_scid[2] = {0,1}; // [HOTFIX] This is a temporary implementation of scramblingID0 and scramblingID1 which are given by DMRS-UplinkConfig @@ -877,6 +877,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, pbch_vars[eNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); pbch_vars[eNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); pbch_vars[eNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pbch_vars[eNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); pbch_vars[eNB_id]->llr = (int16_t *)malloc16_clear( 1920 ); // prach_vars[eNB_id]->prachF = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); prach_vars[eNB_id]->prach = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); @@ -888,6 +889,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int idx = (j<<1)+i; pbch_vars[eNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 ); pbch_vars[eNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) ); + pbch_vars[eNB_id]->dl_ch_estimates_time[idx]= (int32_t *)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) ); pbch_vars[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 ); } } diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 00b2b6a7da..a08abf416a 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -27,10 +27,11 @@ uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 16, 32}; -int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_frame_index) +int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb) { int mu = fp->numerology_index; + uint8_t half_frame_index = fp->half_frame_bit; int symbol = 0; uint8_t n, n_temp; nr_ssb_type_e type = fp->ssb_type; @@ -79,14 +80,17 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_f return symbol; } - int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, - int mu, + nfapi_nr_config_request_scf_t* cfg, + int mu0, int Ncp, - int N_RB_DL) + int N_RB_DL, + int N_RB_UL) { + int mu = cfg!= NULL ? cfg->ssb_config.scs_common.value : mu0; + #if DISABLE_LOG_X printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB_DL, Ncp); #else @@ -96,9 +100,11 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, if (Ncp == NFAPI_CP_EXTENDED) AssertFatal(mu == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, mu); + fp->half_frame_bit = 0; // half frame bit initialized to 0 here fp->numerology_index = mu; fp->Ncp = Ncp; fp->N_RB_DL = N_RB_DL; + fp->N_RB_UL = N_RB_UL; switch(mu) { @@ -224,6 +230,8 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, fp->slots_per_frame = 10* fp->slots_per_subframe; fp->nb_antenna_ports_eNB = 1; // default value until overwritten by RRCConnectionReconfiguration + fp->nb_antennas_rx = 1; // default value until overwritten by RRCConnectionReconfiguration + fp->nb_antennas_tx = 1; // default value until overwritten by RRCConnectionReconfiguration fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe; @@ -231,35 +239,43 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size; fp->samples_per_slot = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size); fp->samples_per_subframe = (fp->samples_per_subframe_wCP + (fp->nb_prefix_samples0 * fp->slots_per_subframe) + - (fp->nb_prefix_samples * fp->slots_per_subframe * (fp->symbols_per_slot - 1))); + (fp->nb_prefix_samples * fp->slots_per_subframe * (fp->symbols_per_slot - 1))); fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2; // definition of Lmax according to ts 38.213 section 4.1 - if (fp->dl_CarrierFreq < 6e9){ - if(fp->frame_type && (fp->ssb_type==2)) - fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8; - else - fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8; - } - else + if (fp->dl_CarrierFreq < 6e9) { + if(fp->frame_type && (fp->ssb_type==2)) + fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8; + else + fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8; + } else { fp->Lmax = 64; + } + fp->N_ssb = 0; + int num_tx_ant = (cfg == NULL) ? fp->Lmax : cfg->carrier_config.num_tx_ant.value; + + for (int p=0; p N_ssb += ((fp->L_ssb >> p) & 0x01); return 0; } -int nr_init_frame_parms(nfapi_nr_config_request_t* config, +int nr_init_frame_parms(nfapi_nr_config_request_scf_t* config, NR_DL_FRAME_PARMS *fp) { - fp->eutra_band = config->nfapi_config.rf_bands.rf_band[0]; - fp->frame_type = !(config->subframe_config.duplex_mode.value); - fp->L_ssb = config->sch_config.ssb_scg_position_in_burst.value; + fp->frame_type = config->cell_config.frame_duplex_type.value; + fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[1].ssb_mask.value)<<32) | config->ssb_table.ssb_mask_list[0].ssb_mask.value ; + int N_RB_DL = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value; + int N_RB_UL = config->carrier_config.ul_grid_size[config->ssb_config.scs_common.value].value; return nr_init_frame_parms0(fp, - config->subframe_config.numerology_index_mu.value, - config->subframe_config.dl_cyclic_prefix_type.value, - config->rf_config.dl_carrier_bandwidth.value); + config, + 0, + NFAPI_CP_NORMAL, + N_RB_DL, + N_RB_UL); } int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, @@ -269,9 +285,9 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, int n_ssb_crb, int ssb_subcarrier_offset) { - /*n_ssb_crb and ssb_subcarrier_offset are given in 15kHz SCS*/ - nr_init_frame_parms0(fp,mu,Ncp,N_RB_DL); - fp->ssb_start_subcarrier = (12 * n_ssb_crb + ssb_subcarrier_offset)/(1< ssb_start_subcarrier = (12 * n_ssb_crb + ssb_subcarrier_offset); return 0; } @@ -286,6 +302,8 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp) LOG_I(PHY,"fp->samples_per_frame_wCP=%d\n",fp->samples_per_frame_wCP); LOG_I(PHY,"fp->samples_per_subframe=%d\n",fp->samples_per_subframe); LOG_I(PHY,"fp->samples_per_frame=%d\n",fp->samples_per_frame); + LOG_I(PHY,"fp->dl_CarrierFreq=%lu\n",fp->dl_CarrierFreq); + LOG_I(PHY,"fp->ul_CarrierFreq=%lu\n",fp->ul_CarrierFreq); } diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h index e136e8a770..f0a1abe0ac 100644 --- a/openair1/PHY/INIT/phy_init.h +++ b/openair1/PHY/INIT/phy_init.h @@ -377,8 +377,8 @@ void phy_config_request(PHY_Config_t *phy_config); int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf); void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms); -int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_frame_index); -int nr_init_frame_parms(nfapi_nr_config_request_t *config, NR_DL_FRAME_PARMS *frame_parms); +int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb); +int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms,int mu,int Ncp,int N_RB_DL,int n_ssb_crb,int ssb_subcarrier_offset); int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag); void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index 3c54e0bd28..cb001f9dc4 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -788,8 +788,9 @@ int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, int16_t Ravg[2]; Ravg[0]=0; Ravg[1]=0; - int16_t iv, rv, phase_idx; - __m128i avg128U1, avg128U2, R[3], mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; + int16_t iv, rv, phase_idx = 0; + __m128i avg128U1, avg128U2, R[3], mmtmpD0, mmtmpD1, mmtmpD2, mmtmpD3; + // round(tan((pi/4)*[1:1:N]/N)*pow2(15)) int16_t alpha[128] = {201, 402, 603, 804, 1006, 1207, 1408, 1610, 1811, 2013, 2215, 2417, 2619, 2822, 3024, 3227, 3431, 3634, 3838, 4042, 4246, 4450, 4655, 4861, 5066, 5272, 5479, 5686, 5893, 6101, 6309, 6518, 6727, 6937, 7147, 7358, 7570, 7782, 7995, 8208, 8422, 8637, 8852, 9068, 9285, 9503, 9721, 9940, 10160, 10381, 10603, 10825, 11049, 11273, 11498, 11725, 11952, 12180, 12410, 12640, 12872, 13104, 13338, 13573, 13809, 14046, 14285, 14525, 14766, 15009, 15253, 15498, 15745, 15993, 16243, 16494, 16747, 17001, 17257, 17515, 17774, 18035, 18298, 18563, 18829, 19098, 19368, 19640, 19915, 20191, 20470, 20750, 21033, 21318, 21605, 21895, 22187, 22481, 22778, 23078, 23380, 23685, 23992, 24302, 24615, 24931, 25250, 25572, 25897, 26226, 26557, 26892, 27230, 27572, 27917, 28266, 28618, 28975, 29335, 29699, 30067, 30440, 30817, 31198, 31583, 31973, 32368, 32767}; // compute log2_maxh (output_shift) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 4d296a7872..2b6d998b73 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -2001,6 +2001,11 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu ulsch->ue_type = ulsch_pdu->ulsch_pdu_rel13.ue_type; AssertFatal(harq_pid ==0 || ulsch->ue_type == NOCE, "Harq PID is not zero for BL/CE UE\n"); + if(ulsch_pdu->ulsch_pdu_rel13.repetition_number >1) // Fill the Harq process parameters in the first Rep only + { + return; + } + //AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb>0,"nb_rb = 0\n"); if(ulsch->harq_processes[harq_pid]->nb_rb == 0) { LOG_E(PHY, "fill_ulsch UE_id %d nb_rb = 0\n", UE_id); @@ -2009,6 +2014,10 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu ulsch->harq_processes[harq_pid]->frame = frame; ulsch->harq_processes[harq_pid]->subframe = subframe; ulsch->harq_processes[harq_pid]->handled = 0; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ulsch->harq_processes[harq_pid]->repetition_number = ulsch_pdu->ulsch_pdu_rel13.repetition_number ; + ulsch->harq_processes[harq_pid]->total_number_of_repetitions = ulsch_pdu->ulsch_pdu_rel13.total_number_of_repetitions ; +#endif ulsch->harq_processes[harq_pid]->first_rb = ulsch_pdu->ulsch_pdu_rel8.resource_block_start; ulsch->harq_processes[harq_pid]->nb_rb = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks; ulsch->harq_processes[harq_pid]->dci_alloc = 1; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index 80e7b6f8cd..6595158f1a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -42,6 +42,7 @@ #include "common/utils/LOG/log.h" #include "targets/RT/USER/lte-softmodem.h" #include +#include "executables/thread-common.h" //#define DEBUG_DLSCH_CODING //#define DEBUG_DLSCH_FREE 1 @@ -57,9 +58,8 @@ uint64_t runtime, uint64_t deadline, uint64_t period);*/ -extern WORKER_CONF_t get_thread_worker_conf(void); -extern volatile int oai_exit; +extern volatile int oai_exit; void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) { int i, r, aa, layer; @@ -99,7 +99,14 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) { } } -LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_t Nsoft,unsigned char N_RB_DL, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS *frame_parms) { + +LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo, + unsigned char Mdlharq, + uint32_t Nsoft, + unsigned char N_RB_DL, + uint8_t abstraction_flag, + LTE_DL_FRAME_PARMS *frame_parms) +{ LTE_eNB_DLSCH_t *dlsch; unsigned char exit_flag = 0,i,j,r,aa,layer; int re; @@ -221,6 +228,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ return(NULL); } + void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) { unsigned char Mdlharq; unsigned char i,j,r; @@ -257,8 +265,6 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) { } - - int dlsch_encoding_2threads0(te_params *tep) { LTE_eNB_DLSCH_t *dlsch = tep->dlsch; unsigned int G = tep->G; @@ -358,7 +364,6 @@ void *te_thread(void *param) { } - int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, unsigned char *a, uint8_t num_pdcch_symbols, @@ -548,6 +553,8 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); return(0); } + + int dlsch_encoding_all(PHY_VARS_eNB *eNB, unsigned char *a, uint8_t num_pdcch_symbols, @@ -812,10 +819,3 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); return(0); } - - - - - - - diff --git a/openair1/PHY/LTE_TRANSPORT/lte_mcs.c b/openair1/PHY/LTE_TRANSPORT/lte_mcs.c index 48951ffdd0..c13876f29a 100644 --- a/openair1/PHY/LTE_TRANSPORT/lte_mcs.c +++ b/openair1/PHY/LTE_TRANSPORT/lte_mcs.c @@ -118,8 +118,7 @@ uint32_t get_TBS_UL(uint8_t mcs, uint16_t nb_rb) { } } - -int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe,uint8_t symbol) { +int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms, uint32_t *rb_alloc, uint8_t mod_order, uint8_t subframe, uint8_t symbol) { int rb,re_pbch_sss=0; int rb_alloc_ind,nsymb; nsymb = (frame_parms->Ncp==NORMAL) ? 14 : 12; @@ -205,7 +204,7 @@ int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_ord return(re_pbch_sss); } -int adjust_G(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe) { +int adjust_G(LTE_DL_FRAME_PARMS *frame_parms, uint32_t *rb_alloc, uint8_t mod_order, uint8_t subframe) { int rb,re_pbch_sss=0; uint8_t rb_alloc_ind; @@ -286,7 +285,16 @@ int adjust_G(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_orde return(0); } -int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe,uint8_t beamforming_mode) { +int get_G(LTE_DL_FRAME_PARMS *frame_parms, + uint16_t nb_rb, + uint32_t *rb_alloc, + uint8_t mod_order, + uint8_t Nl, + uint8_t num_pdcch_symbols, + int frame, + uint8_t subframe, + uint8_t beamforming_mode) +{ int G_adj; if (is_pmch_subframe(frame,subframe,frame_parms) == 0) { @@ -319,8 +327,16 @@ int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint } } - -int get_G_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe,uint8_t beamforming_mode) { +int get_G_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms, + uint16_t nb_rb, + uint32_t *rb_alloc, + uint8_t mod_order, + uint8_t Nl, + uint8_t num_pdcch_symbols, + int frame, + uint8_t subframe, + uint8_t beamforming_mode) +{ //int G_adj; /*if (is_pmch_subframe(frame,subframe,frame_parms) == 0) { G_adj= adjust_G(frame_parms,rb_alloc,mod_order,subframe); @@ -353,13 +369,10 @@ int get_G_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb return((int)frame_parms->N_RB_DL * mod_order * 120); } - // following function requires dlsch_tbs_full.h #include "PHY/LTE_TRANSPORT/dlsch_tbs_full.h" -unsigned char SE2I_TBS(float SE, - unsigned char N_PRB, - unsigned char symbPerRB) { +unsigned char SE2I_TBS(float SE, unsigned char N_PRB, unsigned char symbPerRB) { unsigned char I_TBS= -1; int throughPutGoal = 0; short diffOld = TBStable[0][N_PRB-1] - throughPutGoal; // always positive because of unsigned arithmetic @@ -393,7 +406,6 @@ unsigned char SE2I_TBS(float SE, } //added for ALU icic purpose - uint8_t Get_SB_size(uint8_t n_rb_dl) { if(n_rb_dl<27) return 4; @@ -402,6 +414,4 @@ uint8_t Get_SB_size(uint8_t n_rb_dl) { else return 8; } - - //end ALU's algo diff --git a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h index 67c627ca00..a80023c744 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h @@ -314,6 +314,12 @@ typedef struct { // int calibration_flag; /// delta_TF for power control int32_t delta_TF; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + // PUSCH Repetition Number for the current SF + uint32_t repetition_number ; + // PUSCH Total number of repetitions + uint32_t total_number_of_repetitions; +#endif } LTE_UL_eNB_HARQ_t; typedef struct { diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index e324f76c2b..59fa853c4d 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -553,12 +553,18 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) int G = ulsch_harq->G; unsigned int E; decoder_if_t *tc; + static int32_t pusch_rep_buffer[3*(6144+64)]; + int max_Ncb; if (llr8_flag == 0) tc = *decoder16; else tc = *decoder8; + if(ulsch_harq->repetition_number == 1){ + memset(pusch_rep_buffer,0,(sizeof(int32_t)*3*(6144+64))) ; // reset the buffer every new repetitions + } + for (r=0; r C; r++) { // printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]); // Get Turbo interleaver parameters @@ -592,7 +598,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) 0, //Uplink 1, ulsch_harq->rvidx, - (ulsch_harq->round==0)?1:0, // clear + (ulsch_harq->rvidx==0)?1:0, // clear ulsch_harq->Qm, 1, r, @@ -602,6 +608,27 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) } stop_meas(&eNB->ulsch_rate_unmatching_stats); + + max_Ncb = 3*ulsch_harq->RTC[r]*32 ; + + if(ulsch_harq->total_number_of_repetitions > 1) + { + if (ulsch_harq->rvidx==1) + { // Store the result of HARQ combining in the last emtc repetitions of sequence 0,2,3,1 + for (int nn=0;nn w[r][nn] ; + } + } + if (ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions) + { + for (int nn=0;nn w[r][nn] = pusch_rep_buffer[nn] ; + } + } + } + r_offset += E; start_meas(&eNB->ulsch_deinterleaving_stats); sub_block_deinterleaving_turbo(4+Kr, diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index ab3271c61c..79e220ac37 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -50,6 +50,7 @@ #include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/LTE_TRANSPORT/transport_eNB.h" #include "modulation_eNB.h" +#include "nr_modulation.h" #include "common/utils/LOG/vcd_signal_dumper.h" int beam_precoding(int32_t **txdataF, @@ -135,3 +136,33 @@ int beam_precoding_one_eNB(int32_t **txdataF, } return 0; } + + +int nr_beam_precoding(int32_t **txdataF, + int32_t **txdataF_BF, + NR_DL_FRAME_PARMS *frame_parms, + int32_t ***beam_weights, + int slot, + int symbol, + int aa, + int nb_antenna_ports) +{ + + + uint8_t p; + + // clear txdata_BF[aa][re] for each call of ue_spec_beamforming + memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size)); + + for (p=0; p L_ssb >> p) & 0x01) { + multadd_cpx_vector((int16_t*)&txdataF[p][symbol*frame_parms->ofdm_symbol_size], + (int16_t*)beam_weights[p][aa], + (int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size], + 0, + frame_parms->ofdm_symbol_size, + 15); + } + } + return 0; +} diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 40099f4739..5c8fce3c38 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -24,7 +24,7 @@ extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT]; void nr_modulation(uint32_t *in, - uint16_t length, + uint32_t length, uint16_t mod_order, int16_t *out) { @@ -51,9 +51,10 @@ void nr_modulation(uint32_t *in, } void nr_layer_mapping(int16_t **mod_symbs, - uint8_t n_layers, - uint16_t n_symbs, - int16_t **tx_layers) { + uint8_t n_layers, + uint16_t n_symbs, + int16_t **tx_layers) { + LOG_D(PHY,"Doing layer mapping for %d layers, %d symbols\n",n_layers,n_symbs); switch (n_layers) { @@ -120,6 +121,103 @@ void nr_layer_mapping(int16_t **mod_symbs, } } +void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, + uint8_t n_layers, + uint16_t n_symbs, + int16_t **tx_layers) { + + int16_t *mod_symbs; + + switch (n_layers) { + + case 1: + mod_symbs = (int16_t *)ulsch_ue[0]->d_mod; + for (int i=0; i >15; + tx_layers[0][(i<<1)+1] = (mod_symbs[(i<<1)+1]*AMP)>>15; + } + break; + + case 2: + case 3: + case 4: + mod_symbs = (int16_t *)ulsch_ue[0]->d_mod; + + for (int i=0; i >15; + tx_layers[l][(i<<1)+1] = (mod_symbs[((n_layers*i+l)<<1)+1]*AMP)>>15; + } + } + break; + + case 5: + mod_symbs = (int16_t *)ulsch_ue[0]->d_mod; + + for (int i=0; i >1; i++) + for (int l=0; l<2; l++) { + tx_layers[l][i<<1] = (mod_symbs[((i<<1)+l)<<1]*AMP)>>15; + tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<1)+l)<<1)+1]*AMP)>>15; + } + + mod_symbs = (int16_t *)ulsch_ue[1]->d_mod; + + for (int i=0; i >15; + tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15; + } + break; + + case 6: + for (int q=0; q<2; q++){ + + mod_symbs = (int16_t *)ulsch_ue[q]->d_mod; + + for (int i=0; i >15; + tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15; + } + } + break; + + case 7: + mod_symbs = (int16_t *)ulsch_ue[1]->d_mod; + + for (int i=0; i >15; + tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15; + } + + mod_symbs = (int16_t *)ulsch_ue[0]->d_mod; + + for (int i=0; i >15; + tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<2)+l)<<1)+1]*AMP)>>15; + } + break; + + case 8: + for (int q=0; q<2; q++){ + + mod_symbs = (int16_t *)ulsch_ue[q]->d_mod; + + for (int i=0; i >2; i++) + for (int l=0; l<3; l++) { + tx_layers[l][i<<1] = (mod_symbs[((i<<2)+l)<<1]*AMP)>>15; + tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<2)+l)<<1)+1]*AMP)>>15; + } + } + break; + + default: + AssertFatal(0, "Invalid number of layers %d\n", n_layers); + } +} + void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) { diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 249a92e8e3..706b4dc113 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -25,6 +25,7 @@ #include #include "PHY/defs_nr_common.h" #include "PHY/defs_gNB.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" #define DMRS_MOD_ORDER 2 @@ -36,7 +37,7 @@ */ void nr_modulation(uint32_t *in, - uint16_t length, + uint32_t length, uint16_t mod_order, int16_t *out); @@ -52,6 +53,18 @@ void nr_layer_mapping(int16_t **mod_symbs, uint16_t n_symbs, int16_t **tx_layers); +/*! \brief Perform NR layer mapping. TS 38.211 V15.4.0 subclause 7.3.1.3 + @param[in] ulsch_ue, double Pointer to NR_UE_ULSCH_t struct + @param[in] n_layers, number of layers + @param[in] n_symbs, number of modulated symbols + @param[out] tx_layers, modulated symbols for each layer +*/ + +void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, + uint8_t n_layers, + uint16_t n_symbs, + int16_t **tx_layers); + /*! \brief This function implements the OFDM front end processor on reception (FEP) @@ -80,4 +93,14 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, */ void nr_dft(int32_t *z,int32_t *d, uint32_t Msc_PUSCH); -#endif \ No newline at end of file +int nr_beam_precoding(int32_t **txdataF, + int32_t **txdataF_BF, + NR_DL_FRAME_PARMS *frame_parms, + int32_t ***beam_weights, + int slot, + int symbol, + int aa, + int nb_antenna_ports +); + +#endif diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index b23fd2e2bf..cbeeca1327 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -86,6 +86,8 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input ) { + if(nb_symbols == 0) return; + short temp[4096*4] __attribute__((aligned(32))); unsigned short i,j; short k; diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index c00fef5929..11aaf1f78e 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -36,10 +36,10 @@ #endif*/ int nr_slot_fep(PHY_VARS_NR_UE *ue, - unsigned char symbol, - unsigned char Ns, - int sample_offset, - int no_prefix) + unsigned char symbol, + unsigned char Ns, + int sample_offset, + int no_prefix) { NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_UE_COMMON *common_vars = &ue->common_vars; @@ -131,8 +131,8 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, #ifdef DEBUG_FEP // if (ue->frame <100) - /*LOG_I(PHY,*/printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", ue->proc.proc_rxtx[(Ns)&1].frame_rx,Ns, symbol, - nb_prefix_samples,nb_prefix_samples0,slot_offset,sample_offset,rx_offset,frame_length_samples); + /*LOG_I(PHY,*/printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n", + ue->proc.proc_rxtx[(Ns)&1].frame_rx, Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples); #endif if (symbol==0) { @@ -192,7 +192,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, #ifdef DEBUG_FEP // if (ue->frame <100) - printf("slot_fep: frame %d: symbol %d rx_offset %d\n", ue->proc.proc_rxtx[(Ns)&1].frame_rx, symbol,rx_offset); + printf("slot_fep: frame %d: symbol %d rx_offset %u\n", ue->proc.proc_rxtx[(Ns)&1].frame_rx, symbol, rx_offset); #endif } diff --git a/openair1/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c new file mode 100644 index 0000000000..9c4d1fcc93 --- /dev/null +++ b/openair1/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c @@ -0,0 +1,71 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c +* \brief TA estimation for TA updates +* \author Ahmed Hussein +* \date 2019 +* \version 0.1 +* \company Fraunhofer IIS +* \email: ahmed.hussein@iis.fraunhofer.de +* \note +* \warning +*/ + +#include "PHY/types.h" +#include "PHY/defs_gNB.h" +#include "PHY/phy_extern.h" +#include "nr_ul_estimation.h" + +int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id) +{ + int temp, i, aa, max_pos = 0, max_val = 0; + short Re, Im; + uint8_t cyclic_shift = 0; + + NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; + NR_gNB_PUSCH *gNB_pusch_vars = gNB->pusch_vars[UE_id]; + int32_t **ul_ch_estimates_time = gNB_pusch_vars->ul_ch_estimates_time; + + int sync_pos = (frame_parms->ofdm_symbol_size - cyclic_shift*frame_parms->ofdm_symbol_size/12) % (frame_parms->ofdm_symbol_size); + + for (i = 0; i < frame_parms->ofdm_symbol_size; i++) { + temp = 0; + + for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)]; + Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)]; + temp += (Re*Re/2) + (Im*Im/2); + } + + if (temp > max_val) { + max_pos = i; + max_val = temp; + } + } + + if (max_pos > frame_parms->ofdm_symbol_size/2) + max_pos = max_pos - frame_parms->ofdm_symbol_size; + + + return max_pos - sync_pos; +} + diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c new file mode 100644 index 0000000000..16fc94a59f --- /dev/null +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -0,0 +1,397 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + +#include + +#include "nr_ul_estimation.h" +#include "PHY/NR_REFSIG/nr_refsig.h" +#include "PHY/NR_UE_ESTIMATION/filt16a_32.h" + +//#define DEBUG_CH + + +int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + uint8_t gNB_offset, + unsigned char Ns, + unsigned short p, + unsigned char symbol, + unsigned short bwp_start_subcarrier, + unsigned short nb_rb_pusch) +{ + int pilot[3280] __attribute__((aligned(16))); + unsigned char aarx; + unsigned short k; + unsigned int pilot_cnt; + int16_t ch[2],*pil,*rxF,*ul_ch; + int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh; + int ch_offset,symbol_offset, length_dmrs, UE_id = 0; + unsigned short n_idDMRS[2] = {0,1}; //to update from pusch config + int32_t temp_in_ifft_0[8192*2] __attribute__((aligned(32))); + int32_t **ul_ch_estimates_time = gNB->pusch_vars[UE_id]->ul_ch_estimates_time; + +#ifdef DEBUG_CH + FILE *debug_ch_est; + debug_ch_est = fopen("debug_ch_est.txt","w"); +#endif + + //uint16_t Nid_cell = (eNB_offset == 0) ? gNB->frame_parms.Nid_cell : gNB->measurements.adj_cell_id[eNB_offset-1]; + + uint8_t nushift; + int **ul_ch_estimates = gNB->pusch_vars[UE_id]->ul_ch_estimates; + int **rxdataF = gNB->common_vars.rxdataF; + + nushift = (p>>1)&1; + gNB->frame_parms.nushift = nushift; + + ch_offset = gNB->frame_parms.ofdm_symbol_size*symbol; + + symbol_offset = gNB->frame_parms.ofdm_symbol_size*symbol; + + k = bwp_start_subcarrier; + int re_offset = k; + +/* +#ifdef DEBUG_CH + printf("PUSCH Channel Estimation : gNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n", gNB_offset,ch_offset,symbol_offset,gNB->frame_parms.ofdm_symbol_size, + gNB->frame_parms.Ncp,l,Ns,k, symbol); +#endif +*/ + switch (nushift) { + case 0: + fl = filt8_l0; + fm = filt8_m0; + fr = filt8_r0; + fmm = filt8_mm0; + fml = filt8_m0; + fmr = filt8_mr0; + fdcl = filt8_dcl0; + fdcr = filt8_dcr0; + fdclh = filt8_dcl0_h; + fdcrh = filt8_dcr0_h; + break; + + case 1: + fl = filt8_l1; + fm = filt8_m1; + fr = filt8_r1; + fmm = filt8_mm1; + fml = filt8_ml1; + fmr = filt8_m1; + fdcl = filt8_dcl1; + fdcr = filt8_dcr1; + fdclh = filt8_dcl1_h; + fdcrh = filt8_dcr1_h; + break; + + default: + printf("pusch_channel_estimation: nushift=%d -> ERROR\n",nushift); + return(-1); + break; + } + + + //------------------generate DMRS------------------// + + length_dmrs = 1; //to update from pusch config + + nr_gold_pusch(gNB, symbol, n_idDMRS, length_dmrs); + + nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch[gNB_offset][Ns][0], &pilot[0], 1000, 0, nb_rb_pusch); + + //------------------------------------------------// + + for (aarx=0; aarx frame_parms.nb_antennas_rx; aarx++) { + + pil = (int16_t *)&pilot[0]; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; + ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; + + memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size)); + +#ifdef DEBUG_PUSCH + printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_UL); + printf("k %d, first_carrier %d\n",k,gNB->frame_parms.first_carrier_offset); + printf("rxF addr %p p %d\n", rxF,p); + printf("ul_ch addr %p nushift %d\n",ul_ch,nushift); +#endif + //if ((gNB->frame_parms.N_RB_UL&1)==0) { + + // Treat first 2 pilots specially (left edge) + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + +#ifdef DEBUG_PUSCH + printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); + printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); + printf("data 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[2],rxF[3],&rxF[2],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fl, + ch, + ul_ch, + 8); + pil+=2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + //for (int i= 0; i<8; i++) + //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); + + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + +#ifdef DEBUG_PUSCH + printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fml, + ch, + ul_ch, + 8); + pil+=2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + //printf("ul_ch addr %p\n",ul_ch); + + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + +#ifdef DEBUG_PUSCH + printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fmm, + ch, + ul_ch, + 8); + + //for (int i= 0; i<16; i++) + //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); + + pil+=2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ul_ch+=8; + + for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pusch-3); pilot_cnt+=2) { + + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); +#ifdef DEBUG_CH + fprintf(debug_ch_est, "pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + //printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fm, + ch, + ul_ch, + 8); + + pil+=2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); +#ifdef DEBUG_PUSCH + printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fmm, + ch, + ul_ch, + 8); + pil+=2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ul_ch+=8; + + } + + // Treat first 2 pilots specially (right edge) + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); +#ifdef DEBUG_PUSCH + printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fm, + ch, + ul_ch, + 8); + + //for (int i= 0; i<8; i++) + //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); + + pil+=2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); +#ifdef DEBUG_PUSCH + printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); + printf("pilot %d: rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fmr, + ch, + ul_ch, + 8); + + pil+=2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ul_ch+=8; + + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); +#ifdef DEBUG_PUSCH + printf("pilot %d: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fr, + ch, + ul_ch, + 8); + + + // check if PRB crosses DC and improve estimates around DC + if ((bwp_start_subcarrier < gNB->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pusch*12 >= gNB->frame_parms.ofdm_symbol_size)) { + ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; + uint16_t idxDC = 2*(gNB->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); + uint16_t idxPil = idxDC/2; + re_offset = k; + pil = (int16_t *)&pilot[0]; + pil += (idxPil-2); + ul_ch += (idxDC-4); + ul_ch = memset(ul_ch, 0, sizeof(int16_t)*10); + re_offset = (re_offset+idxDC/2-2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + // for proper allignment of SIMD vectors + if((gNB->frame_parms.N_RB_UL&1)==0) { + + multadd_real_vector_complex_scalar(fdcl, + ch, + ul_ch-4, + 8); + + pil += 4; + re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + multadd_real_vector_complex_scalar(fdcr, + ch, + ul_ch-4, + 8); + } else { + + multadd_real_vector_complex_scalar(fdclh, + ch, + ul_ch, + 8); + + pil += 4; + re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + multadd_real_vector_complex_scalar(fdcrh, + ch, + ul_ch, + 8); + } + + } +#ifdef DEBUG_PDSCH + ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; + for(uint16_t idxP=0; idxP frame_parms.ofdm_symbol_size*sizeof(int32_t)); + memcpy(temp_in_ifft_0, &ul_ch_estimates[aarx][symbol_offset], nb_rb_pusch * NR_NB_SC_PER_RB * sizeof(int32_t)); + + switch (gNB->frame_parms.ofdm_symbol_size) { + case 128: + idft128((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + case 256: + idft256((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + case 512: + idft512((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + case 1024: + idft1024((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + case 1536: + idft1536((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + case 2048: + idft2048((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + case 4096: + idft4096((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + case 8192: + idft8192((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + default: + idft512((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + } + } + +#ifdef DEBUG_CH + fclose(debug_ch_est); +#endif + + return(0); +} diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h new file mode 100644 index 0000000000..125c166f7d --- /dev/null +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -0,0 +1,52 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef __NR_UL_ESTIMATION_DEFS__H__ +#define __NR_UL_ESTIMATION_DEFS__H__ + + +#include "PHY/defs_gNB.h" +/** @addtogroup _PHY_PARAMETER_ESTIMATION_BLOCKS_ + * @{ + */ + + +/*! +\brief This function performs channel estimation including frequency interpolation +\param gNB Pointer to gNB PHY variables +\param Ns slot number (0..19) +\param p +\param symbol symbol within slot +\param bwp_start_subcarrier, first allocated subcarrier +\param nb_rb_pusch, number of allocated RBs for this UE +*/ + + int32_t nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + uint8_t gNB_offset, + unsigned char Ns, + unsigned short p, + unsigned char symbol, + unsigned short bwp_start_subcarrier, + unsigned short nb_rb_pusch); + +int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id); + +#endif diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h index 9b02d2b1af..5c4f218512 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.h +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h @@ -55,7 +55,7 @@ int pseudo_random_sequence(int M_PN, uint32_t *c, uint32_t cinit); void lte_gold_new(LTE_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_table[20][2][14], uint16_t Nid_cell); void generate_dmrs_pbch(uint32_t dmrs_pbch_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE], uint16_t Nid_cell); uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position); -uint16_t get_dmrs_freq_idx_ul(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); +uint16_t get_dmrs_freq_idx_ul(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); #undef EXTERN diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index e0c17bfb75..182f8b6215 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -36,6 +36,8 @@ #include "refsig_defs_ue.h" #include "PHY/defs_nr_UE.h" +#include "nr_refsig.h" +#include "PHY/defs_gNB.h" /*Table 7.4.1.1.2-1/2 from 38.211 */ int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1}}; @@ -48,14 +50,67 @@ short nr_rx_mod_table[14] = {0,0,23170,-23170,-23170,23170,23170,-23170,23170,2 short nr_rx_nmod_table[14] = {0,0,-23170,23170,23170,-23170,-23170,23170,-23170,-23170,23170,23170,23170,-23170}; +int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, + unsigned int Ns, + unsigned int *nr_gold_pusch, + int32_t *output, + unsigned short p, + unsigned char lp, + unsigned short nb_pusch_rb) +{ + int8_t w,config_type; + short *mod_table; + unsigned char idx=0; + + typedef int array_of_w[2]; + array_of_w *wf; + array_of_w *wt; + + config_type = 0; //to be updated by higher layer + + wf = (config_type==0) ? wf1 : wf2; + wt = (config_type==0) ? wt1 : wt2; + + if (config_type > 1) + LOG_E(PHY,"Bad PUSCH DMRS config type %d\n", config_type); + + if ((p>=1000) && (p<((config_type==0) ? 1008 : 1012))) { + if (gNB->frame_parms.Ncp == NORMAL) { + + for (int i=0; i >5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1); + ((int16_t*)output)[i<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; + ((int16_t*)output)[(i<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; +#ifdef DEBUG_PUSCH + printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", config_type, p, nb_pusch_rb); + printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]); + printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pusch[(i<<1)>>5], (((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1), + (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1]); +#endif + } + } else { + LOG_E(PHY,"extended cp not supported for PUSCH DMRS yet\n"); + } + } else { + LOG_E(PHY,"Illegal p %d PUSCH DMRS port\n",p); + } + + return(0); +} + + int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, - unsigned int Ns, - unsigned int *nr_gold_pdsch, - int32_t *output, - unsigned short p, - unsigned char lp, - unsigned short nb_pdsch_rb) + unsigned int Ns, + unsigned int *nr_gold_pdsch, + int32_t *output, + unsigned short p, + unsigned char lp, + unsigned short nb_pdsch_rb) { int8_t w,config_type; short *mod_table; @@ -101,15 +156,15 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, return(0); } -int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, - uint8_t eNB_offset, - unsigned int Ns, - unsigned int *nr_gold_pdcch, - int32_t *output, - unsigned short p, - unsigned short nb_rb_coreset) -{ +int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, + uint8_t eNB_offset, + unsigned int Ns, + unsigned int *nr_gold_pdcch, + int32_t *output, + unsigned short p, + unsigned short nb_rb_coreset) +{ uint8_t idx=0; //uint8_t pdcch_rb_offset =0; //nr_gold_pdcch += ((int)floor(ue->frame_parms.ssb_start_subcarrier/12)+pdcch_rb_offset)*3/32; @@ -121,8 +176,8 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, ((int16_t*)output)[(i<<1)+1] = nr_rx_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; #ifdef DEBUG_PDCCH if (i<8) - printf("i %d idx %d pdcch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pdcch[(i<<1)>>5], (((nr_gold_pdcch[(i<<1)>>5])>>((i<<1)&0x1f))&1), - (((nr_gold_pdcch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1],&output[0]); + printf("i %d idx %d pdcch gold %u b0-b1 %d-%d mod_dmrs %d %d addr %p\n", i, idx, nr_gold_pdcch[(i<<1)>>5], (((nr_gold_pdcch[(i<<1)>>5])>>((i<<1)&0x1f))&1), + (((nr_gold_pdcch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1],&output[0]); #endif } } @@ -130,7 +185,10 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, return(0); } -int nr_pbch_dmrs_rx(int symbol,unsigned int *nr_gold_pbch,int32_t *output ) + +int nr_pbch_dmrs_rx(int symbol, + unsigned int *nr_gold_pbch, + int32_t *output) { int m,m0,m1; uint8_t idx=0; @@ -164,6 +222,3 @@ int nr_pbch_dmrs_rx(int symbol,unsigned int *nr_gold_pbch,int32_t *output ) return(0); } - - - diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c index 1492d7f03f..7057adef21 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold.c +++ b/openair1/PHY/NR_REFSIG/nr_gold.c @@ -26,11 +26,11 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB) unsigned int x1, x2; uint16_t Nid, i_ssb, i_ssb2; unsigned char Lmax, l, n_hf, N_hf; - nfapi_nr_config_request_t *cfg = &gNB->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; uint8_t reset; - Nid = cfg->sch_config.physical_cell_id.value; + Nid = cfg->cell_config.phy_cell_id.value; Lmax = fp->Lmax; N_hf = (Lmax == 4)? 2:1; @@ -65,7 +65,7 @@ void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid) for (uint8_t symb=0; symb symbols_per_slot; symb++) { reset = 1; - x2 = ((1<<17) * (14*slot+symb+1) * ((Nid<<1)+1) + (Nid<<1)); + x2 = ((1<<17) * (14*slot+symb+1) * ((Nid<<1)+1)) + (Nid<<1); for (uint32_t n=0; n symbols_per_slot; symb++) { reset = 1; x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid[n_scid]<<1)+1) +((N_n_scid[n_scid]<<1)+n_scid)); + LOG_D(PHY,"DMRS slot %d, symb %d x2 %x\n",slot,symb,x2); for (uint32_t n=0; n frame_parms.Nid_cell; + + //printf("gold pdsch nid %d lbar %d\n",nid,lbar); + + for (ns=0; ns<20; ns++) { + + for (l=0; l >1) ^ (x2>>2) ^ (x2>>3))<<31); + + // skip first 50 double words (1600 bits) + for (n=1; n<50; n++) { + x1 = (x1>>1) ^ (x1>>4); + x1 = x1 ^ (x1<<31) ^ (x1<<28); + x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4); + x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28); + //printf("x1 : %x, x2 : %x\n",x1,x2); + } + + for (n=0; n >1) ^ (x1>>4); + x1 = x1 ^ (x1<<31) ^ (x1<<28); + x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4); + x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28); + gNB->nr_gold_pusch[nscid][ns][l][n] = x1^x2; + // if ((ns==2)&&(l==0)) + //printf("n=%d : c %x\n",n,x1^x2); + } + + } + } + } +} diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index ad26356abb..39ab13b1f1 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c +++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c @@ -100,7 +100,7 @@ void nr_gold_pdcch(PHY_VARS_NR_UE* ue, x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4); x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28); ue->nr_gold_pdcch[0][ns][l][n] = x1^x2; - //printf("n=%d : c %x\n",n,x1^x2); + // if (ns==1 && l==0) printf("n=%d : c %x\n",n,x1^x2); } } } @@ -133,7 +133,7 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue, x2tmp0 = ((14*ns+(lbar+l)+1)*((nid<<1)+1))<<17; x2 = (x2tmp0+(nid<<1)+nscid)%(1<<31); //cinit - + LOG_D(PHY,"UE DMRS slot %d, symb %d, lbar %d, x2 %x, nscid %d\n",ns,l,lbar,x2,nscid); //printf("ns %d gold pdsch x2 %d\n",ns,x2); x1 = 1+ (1<<31); @@ -148,7 +148,7 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue, //printf("x1 : %x, x2 : %x\n",x1,x2); } - for (n=0; n<52; n++) { + for (n=0; n >1) ^ (x1>>4); x1 = x1 ^ (x1<<31) ^ (x1<<28); x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4); diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index cb165eed5e..e1bfa1420d 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -39,4 +39,13 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB); void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid); void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid); +void nr_gold_pusch(PHY_VARS_gNB* gNB, unsigned short lbar,unsigned short *n_idDMRS, unsigned short length_dmrs); + +int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, + unsigned int Ns, + unsigned int *nr_gold_pusch, + int32_t *output, + unsigned short p, + unsigned char lp, + unsigned short nb_pusch_rb); #endif diff --git a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c index 1a64c8902c..8521a2618f 100644 --- a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c +++ b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c @@ -54,7 +54,9 @@ * *********************************************************************/ -int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling) +int16_t *base_sequence_less_than_36(unsigned int M_ZC, + unsigned int u, + unsigned int scaling) { char *phi_table; int16_t *rv_overbar; @@ -77,7 +79,7 @@ int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned case 30: break; default: - printf("function base_sequence_less_than 36_: unsupported base sequence size : %d \n", M_ZC); + printf("function base_sequence_less_than 36_: unsupported base sequence size : %u \n", M_ZC); assert(0); break; } @@ -121,7 +123,10 @@ int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned * *********************************************************************/ -int16_t *base_sequence_36_or_larger(unsigned int Msc_RS, unsigned int u, unsigned int v, unsigned int scaling) +int16_t *base_sequence_36_or_larger(unsigned int Msc_RS, + unsigned int u, + unsigned int v, + unsigned int scaling) { int16_t *rv_overbar; unsigned int N_ZC; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index a48ed7e37b..c661fbd292 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -42,8 +42,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, nfapi_nr_rnti_type_e rnti_type, - uint16_t N_RB, - nfapi_nr_config_request_t *config) { + uint16_t N_RB) { uint16_t size = 0; switch(format) { @@ -52,7 +51,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, /// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20 size += 20; size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment -- hopping scenario to be updated - size += nr_get_dci_size(NFAPI_NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB, config) - size; // Padding to match 1_0 size + size += nr_get_dci_size(NFAPI_NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB) - size; // Padding to match 1_0 size // UL/SUL indicator assumed to be 0 break; @@ -130,7 +129,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, } void nr_pdcch_scrambling(uint32_t *in, - uint16_t size, + uint32_t size, uint32_t Nid, uint32_t n_RNTI, uint32_t *out) { @@ -138,7 +137,6 @@ void nr_pdcch_scrambling(uint32_t *in, uint32_t x1, x2, s=0; reset = 1; x2 = (n_RNTI<<16) + Nid; - for (int i=0; i >(i&0x1f))&1) ^ ((s>>(i&0x1f))&1))<<(i&0x1f); - //printf("nr_pdcch_scrambling: in %d seq 0x%08x => out %d\n",((*in)>>(i&0x1f))&1,s,((*out)>>(i&0x1f))&1); } } -uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, + +uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu, + nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu, uint32_t **gold_pdcch_dmrs, int32_t *txdataF, int16_t amp, - NR_DL_FRAME_PARMS frame_parms, - nfapi_nr_config_request_t config) { + NR_DL_FRAME_PARMS frame_parms) { + int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1]; // 3 for the max coreset duration - uint32_t dmrs_seq[NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD]; - uint16_t dmrs_offset=0; uint16_t cset_start_sc; uint8_t cset_start_symb, cset_nsymb; int k,l,k_prime,dci_idx, dmrs_idx; - nr_cce_t cce; - nr_reg_t reg; - nr_reg_t reg_mapping_list[NR_MAX_PDCCH_AGG_LEVEL*NR_NB_REG_PER_CCE]; /*First iteration: single DCI*/ - NR_gNB_DCI_ALLOC_t dci_alloc = pdcch_vars.dci_alloc[0]; - nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc.pdcch_params; - /*The coreset is initialised - * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0 - * or the rb_offset for other coresets - * in time: by its first slot and its first symbol*/ - if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1) { + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15; + + + // find coreset descriptor + + int rb_offset; + int n_rb; + + AssertFatal(pdcch_pdu==NULL || ul_dci_pdu==NULL,"Can't handle both DL and UL DCI in same slot\n"); + + if (pdcch_pdu) pdcch_pdu_rel15 = &pdcch_pdu->pdcch_pdu_rel15; + else if (ul_dci_pdu) pdcch_pdu_rel15 = &ul_dci_pdu->pdcch_pdu.pdcch_pdu_rel15; + + get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset); + + // compute rb_offset and n_prb based on frequency allocation + + if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) { cset_start_sc = frame_parms.first_carrier_offset + (frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB + - pdcch_params.rb_offset)*NR_NB_SC_PER_RB; + rb_offset)*NR_NB_SC_PER_RB; } else - cset_start_sc = frame_parms.first_carrier_offset + pdcch_params.rb_offset*NR_NB_SC_PER_RB; + cset_start_sc = frame_parms.first_carrier_offset + rb_offset*NR_NB_SC_PER_RB; - cset_start_symb = pdcch_params.first_symbol; - cset_nsymb = pdcch_params.n_symb; - dci_idx = 0; - LOG_D(PHY, "Coreset rb_offset %d\n",pdcch_params.rb_offset); - LOG_D(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb); - // DMRS length is per OFDM symbol - uint16_t dmrs_length = (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS)? - (pdcch_params.n_rb*6) : (dci_alloc.L*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE) - uint16_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE) - LOG_D(PHY, "DMRS length per symbol %d\t DCI encoded length %d\n", dmrs_length, encoded_length); + for (int d=0;d numDlDci;d++) { + /*The coreset is initialised + * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0 + * or the rb_offset for other coresets + * in time: by its first slot and its first symbol*/ - /// DMRS QPSK modulation - /*There is a need to shift from which index the pregenerated DMRS sequence is used - * see 38211 r15.2.0 section 7.4.1.3.2: assumption is the reference point for k refers to the DMRS sequence*/ - if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) { - for (int symb=cset_start_symb; symb >5; - - dmrs_offset = (pdcch_params.rb_offset*3)&0x1f; - LOG_D(PHY, "PDCCH DMRS offset %d\n", dmrs_offset); - } - - for (int symb=cset_start_symb; symb >5)] |= ((gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]>>((i+dmrs_offset)&0x1f))&1)<<(i&0x1f); -#ifdef DEBUG_PDCCH_DMRS - //printf("out 0x%08x in 0x%08x \n", dmrs_seq[(i>>5)], gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]); -#endif - } - - nr_modulation(dmrs_seq, dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated - } else + cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex; + cset_nsymb = pdcch_pdu_rel15->DurationSymbols; + dci_idx = 0; + LOG_D(PHY, "Coreset rb_offset %d, nb_rb %d\n",rb_offset,n_rb); + LOG_D(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb); + // DMRS length is per OFDM symbol + AssertFatal(pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED, + "Interleaved CCE REG MAPPING not supported\n"); + uint32_t dmrs_length = (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED)? + (n_rb*6) : (pdcch_pdu_rel15->AggregationLevel[d]*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE) + uint32_t encoded_length = pdcch_pdu_rel15->AggregationLevel[d]*108; //2(QPSK)*9(per RB)*6(REG per CCE) + LOG_D(PHY, "DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d,reg_mapping %d)\n", dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType); + dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset + + /// DMRS QPSK modulation + for (int symb=cset_start_symb; symb DurationSymbols; symb++) { + nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated - + #ifdef DEBUG_PDCCH_DMRS - - for (int i=0; i >1; i++) - if (dmrs_offset) - printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i, dmrs_seq[i>>5], - mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] ); - else - printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i, - gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] ); - + + for (int i=0; i >1; i++) + printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i, + gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] ); + #endif - } - - /// DCI payload processing - // CRC attachment + Scrambling + Channel coding + Rate matching - uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD]; - uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params.rnti:0; - uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? - pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value; - t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L); - polar_encoder_fast(dci_alloc.dci_pdu, encoder_output, pdcch_params.rnti,currentPtr); + } + + /// DCI payload processing + // CRC attachment + Scrambling + Channel coding + Rate matching + uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD]; + uint16_t n_RNTI = pdcch_pdu_rel15->RNTI[d]; + uint16_t Nid = pdcch_pdu_rel15->ScramblingId[d]; + + t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, + pdcch_pdu_rel15->PayloadSizeBits[d], + pdcch_pdu_rel15->AggregationLevel[d], + 0,NULL); + polar_encoder_fast((uint64_t*)pdcch_pdu_rel15->Payload[d], encoder_output, n_RNTI,1,currentPtr); #ifdef DEBUG_CHANNEL_CODING - printf("polar rnti %d\n",pdcch_params.rnti); - printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n", - dci_alloc.dci_pdu[0], dci_alloc.dci_pdu[1]); - printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5); - - for (int i=0; i >5; i++) - printf("[%d]->0x%08x \t", i,encoder_output[i]); - - printf("\n"); + printf("polar rnti %x,length %d, L %d\n",n_RNTI, pdcch_pdu_rel15->PayloadSizeBits[d],pdcch_pdu_rel15->AggregationLevel[d]); + printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n", + ((uint64_t*)pdcch_pdu_rel15->Payload[d])[0], ((uint64_t*)pdcch_pdu_rel15->Payload[d])[1]); + printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5); + + for (int i=0; i >5; i++) + printf("[%d]->0x%08x \t", i,encoder_output[i]); + + printf("\n"); #endif - /// Scrambling - uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD]= {0}; - nr_pdcch_scrambling(encoder_output, encoded_length, Nid, n_RNTI, scrambled_output); + /// Scrambling + uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD]= {0}; + nr_pdcch_scrambling(encoder_output, encoded_length, Nid, n_RNTI, scrambled_output); #ifdef DEBUG_CHANNEL_CODING - printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\t [4]->0x%08x\t [5]->0x%08x\t \ + printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\t [4]->0x%08x\t [5]->0x%08x\t \ [6]->0x%08x \t [7]->0x%08x \t [8]->0x%08x \t [9]->0x%08x\t [10]->0x%08x\t [11]->0x%08x\n", - scrambled_output[0], scrambled_output[1], scrambled_output[2], scrambled_output[3], scrambled_output[4],scrambled_output[5], - scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] ); + scrambled_output[0], scrambled_output[1], scrambled_output[2], scrambled_output[3], scrambled_output[4],scrambled_output[5], + scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] ); #endif - /// QPSK modulation - int16_t mod_dci[NR_MAX_DCI_SIZE>>1]; - nr_modulation(scrambled_output, encoded_length, DMRS_MOD_ORDER, mod_dci); //Qm = 2 as DMRS is QPSK modulated + /// QPSK modulation + int16_t mod_dci[NR_MAX_DCI_SIZE>>1]; + nr_modulation(scrambled_output, encoded_length, DMRS_MOD_ORDER, mod_dci); //Qm = 2 as DMRS is QPSK modulated #ifdef DEBUG_DCI - - for (int i=0; i >1; i++) - printf("i %d mod_dci %d %d\n", i, mod_dci[i<<1], mod_dci[(i<<1)+1] ); - + + for (int i=0; i >1; i++) + printf("i %d mod_dci %d %d\n", i, mod_dci[i<<1], mod_dci[(i<<1)+1] ); + #endif + + /// Resource mapping + + if (cset_start_sc >= frame_parms.ofdm_symbol_size) + cset_start_sc -= frame_parms.ofdm_symbol_size; + + /*Reorder REG list for a freq first mapping*/ + uint8_t nb_regs = pdcch_pdu_rel15->AggregationLevel[d]*NR_NB_REG_PER_CCE; - /// Resource mapping - - if (cset_start_sc >= frame_parms.ofdm_symbol_size) - cset_start_sc -= frame_parms.ofdm_symbol_size; - - /*Reorder REG list for a freq first mapping*/ - uint8_t symb_idx[NR_MAX_CSET_DURATION] = {0,0,0}; - uint8_t nb_regs = dci_alloc.L*NR_NB_REG_PER_CCE; - uint8_t regs_per_symb = nb_regs/cset_nsymb; - - for (int cce_idx=0; cce_idx >1) * mod_dmrs[l][dmrs_idx<<1]) >> 15; - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp>>1) * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; -#ifdef DEBUG_PDCCH_DMRS - printf("symbol %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1], - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); -#endif - k+=4; - - if (k >= frame_parms.ofdm_symbol_size) - k -= frame_parms.ofdm_symbol_size; - - dmrs_idx++; - } - } - } - - /*Now mapping the encoded DCI based on newly constructed REG list - * and the DMRS for the precoder granularity same as REG bundle*/ - for (int reg_idx=0; reg_idx = frame_parms.ofdm_symbol_size) - k -= frame_parms.ofdm_symbol_size; - - l = cset_start_symb + reg.symb_idx; - dmrs_idx = (reg.reg_idx/cset_nsymb)*3; - k_prime = 0; - - for (int m=0; m >1) * mod_dmrs[l][dmrs_idx<<1]) >> 15; - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp>>1) * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; -#ifdef DEBUG_PDCCH_DMRS - printf("l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1], - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); -#endif - dmrs_idx++; - } - - k_prime++; - } else { // DCI payload - ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dci[dci_idx<<1]) >> 15; - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dci[(dci_idx<<1) + 1]) >> 15; -#ifdef DEBUG_DCI - printf("l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1], - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); -#endif - dci_idx++; - } - - k++; - + /*Mapping the encoded DCI along with the DMRS */ + for (int reg_idx=0; reg_idx = frame_parms.ofdm_symbol_size) - k -= frame_parms.ofdm_symbol_size; - } - } - + k -= frame_parms.ofdm_symbol_size; + + l = cset_start_symb + ((reg_idx/cset_nsymb)%cset_nsymb); + + // dmrs index depends on reference point for k according to 38.211 7.4.1.3.2 + if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) + dmrs_idx = (reg_idx/cset_nsymb)*3; + else + dmrs_idx = ((reg_idx/cset_nsymb)+rb_offset)*3; + + k_prime = 0; + + for (int m=0; m CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED) { + ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (2*amp * mod_dmrs[l][dmrs_idx<<1]) >> 15; + ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (2*amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; +#ifdef DEBUG_PDCCH_DMRS + printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1], + ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); +#endif + dmrs_idx++; + } + + k_prime++; + } else { // DCI payload + ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dci[dci_idx<<1]) >> 15; + ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dci[(dci_idx<<1) + 1]) >> 15; +#ifdef DEBUG_DCI + printf("PDCCH: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1], + ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); +#endif + dci_idx++; + } + + k++; + + if (k >= frame_parms.ofdm_symbol_size) + k -= frame_parms.ofdm_symbol_size; + } // m + } // reg_idx + } // for (int d=0;d numDlDci;d++) return 0; } + diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h index f246eaf18e..047139aa63 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h @@ -27,29 +27,31 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, nfapi_nr_rnti_type_e rnti_type, - uint16_t N_RB, - nfapi_nr_config_request_t *config); + uint16_t N_RB); -uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, +uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu, + nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu, uint32_t **gold_pdcch_dmrs, int32_t *txdataF, int16_t amp, - NR_DL_FRAME_PARMS frame_parms, - nfapi_nr_config_request_t config); + NR_DL_FRAME_PARMS frame_parms); void nr_pdcch_scrambling(uint32_t *in, - uint16_t size, + uint32_t size, uint32_t Nid, uint32_t n_RNTI, uint32_t *out); void nr_fill_dci(PHY_VARS_gNB *gNB, int frame, - int slot, - NR_gNB_DCI_ALLOC_t *dci_alloc, - nfapi_nr_dl_config_dci_dl_pdu *pdu); + int slot); -void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t *dci_alloc, uint16_t n_shift, uint8_t m); +void nr_fill_ul_dci(PHY_VARS_gNB *gNB, + int frame, + int slot); +void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m); + +void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset); #endif //__PHY_NR_TRANSPORT_DCI__H diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c index 1c5b041657..ccec73d40e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c @@ -32,15 +32,18 @@ #include "nr_dci.h" -#define DEBUG_FILL_DCI +//#define DEBUG_FILL_DCI #include "nr_dlsch.h" -void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m) { +/* + Original version to keep code for Y that needs to be moved to MAC + +void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint16_t n_shift, uint8_t m) { nr_cce_t* cce; nr_reg_t* reg; - nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params = &dci_alloc->pdcch_params; + nfapi_nr_dl_config_pdcch_pdu_rel15_t* pdcch_pdu = gNB->pdcch_pdu.pdcch; uint8_t L = dci_alloc->L; uint8_t bsize = pdcch_params->reg_bundle_size; @@ -54,7 +57,7 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L); N_cce = N_reg / NR_NB_REG_PER_CCE; - /*Max number of candidates per aggregation level -- SIB1 configured search space only*/ + //Max number of candidates per aggregation level -- SIB1 configured search space only M_s_max = (L==4)?4:(L==8)?2:1; if (pdcch_params->search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_COMMON) @@ -113,6 +116,84 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m } } +*/ + +void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m) { + + nr_cce_t* cce; + nr_reg_t* reg; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu_rel15 = &gNB->pdcch_pdu->pdcch_pdu_rel15; + int bsize = pdcch_pdu_rel15->RegBundleSize; + int R = pdcch_pdu_rel15->InterleaverSize; + int n_shift = pdcch_pdu_rel15->ShiftIndex; + + + //Max number of candidates per aggregation level -- SIB1 configured search space only + + + int n_rb,rb_offset; + + get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset); + + + int N_reg = n_rb * pdcch_pdu_rel15->DurationSymbols; + int C; + + for (int d=0;d numDlDci;d++) { + int L = pdcch_pdu_rel15->AggregationLevel[d]; + + if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) + AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L); + + if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { + uint16_t assertFatalCond = (N_reg%(bsize*R)); + AssertFatal(assertFatalCond == 0,"CCE to REG interleaving: Invalid configuration leading to non integer C (N_reg %us, bsize %d R %d)\n",N_reg, bsize, R); + C = N_reg/(bsize*R); + } + + LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->CceIndex[d]); + for (uint8_t cce_idx=0; cce_idx cce_list[d][cce_idx]; + cce->cce_idx = pdcch_pdu_rel15->CceIndex[d] + cce_idx; + LOG_D(PHY, "cce_idx %d\n", cce->cce_idx); + + if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { + LOG_D(PHY, "Interleaved CCE to REG mapping\n"); + uint8_t j = cce->cce_idx, j_prime; + uint8_t r,c,idx; + + for (uint8_t bundle_idx=0; bundle_idx reg_list[reg_idx]; + reg->reg_idx = bsize*idx + reg_idx; + reg->start_sc_idx = (reg->reg_idx/pdcch_pdu_rel15->DurationSymbols) * NR_NB_SC_PER_RB; + reg->symb_idx = reg->reg_idx % pdcch_pdu_rel15->DurationSymbols; + LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx); + } + } + } + else { // NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED + LOG_D(PHY, "Non interleaved CCE to REG mapping\n"); + for (uint8_t reg_idx=0; reg_idx reg_list[reg_idx]; + reg->reg_idx = cce->cce_idx*NR_NB_REG_PER_CCE + reg_idx; + reg->start_sc_idx = (reg->reg_idx/pdcch_pdu_rel15->DurationSymbols) * NR_NB_SC_PER_RB; + reg->symb_idx = reg->reg_idx % pdcch_pdu_rel15->DurationSymbols; + LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx); + } + + } + + } + } +} + /*static inline uint64_t dci_field(uint64_t field, uint8_t size) { uint64_t ret = 0; for (int i=0; i dci_pdu; - memset((void*)dci_pdu,0,2*sizeof(uint64_t)); - nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &pdcch_pdu->dci_dl_pdu_rel15; - nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &pdcch_pdu->pdcch_params_rel15; - - - nfapi_nr_config_request_t *cfg = &gNB->gNB_config; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &gNB->pdcch_pdu->pdcch_pdu_rel15; NR_gNB_DLSCH_t *dlsch; - uint16_t N_RB = params_rel15->n_RB_BWP; - uint8_t fsize=0, pos=0, cand_idx=0; + for (int i=0;i numDlDci;i++) { + + uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i]; - - int dlsch_id = find_nr_dlsch(params_rel15->rnti,gNB,SEARCH_EXIST_OR_FREE); - if( (dlsch_id<0) || (dlsch_id>=NUMBER_OF_NR_DLSCH_MAX) ){ - LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",params_rel15->rnti,dlsch_id); - return; - } - - dlsch = gNB->dlsch[dlsch_id][0]; - - dlsch->slot_tx[slot] = 1; - dlsch->harq_ids[frame%2][slot] = pdu_rel15->harq_pid; - AssertFatal(pdu_rel15->harq_pid < 8 && pdu_rel15->harq_pid >= 0, - "illegal harq_pid %d\n",pdu_rel15->harq_pid); - - dlsch->harq_mask |= (1< harq_pid); - dlsch->rnti = params_rel15->rnti; - - dci_alloc->L = 8; - memcpy((void*)&dci_alloc->pdcch_params, (void*)params_rel15, sizeof(nfapi_nr_dl_config_pdcch_parameters_rel15_t)); - dci_alloc->size = nr_get_dci_size(dci_alloc->pdcch_params.dci_format, - dci_alloc->pdcch_params.rnti_type, - N_RB, - cfg); - - AssertFatal(dci_alloc->size<=64, "DCI sizes above 64 bits not yet supported"); - n_shift = (dci_alloc->pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1)? - cfg->sch_config.physical_cell_id.value : dci_alloc->pdcch_params.shift_index; - nr_fill_cce_list(dci_alloc, n_shift, cand_idx); - - /// Payload generation - switch(params_rel15->dci_format) { - - - case NFAPI_NR_DL_DCI_FORMAT_1_0: - switch(params_rel15->rnti_type) { - case NFAPI_NR_RNTI_RA: - - // Freq domain assignment - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - pos=fsize; - *dci_pdu |= ((pdu_rel15->frequency_domain_assignment&((1< size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"frequency-domain assignment %d (%d bits) N_RB_BWP %d=> %d (0x%lx)\n",pdu_rel15->frequency_domain_assignment,fsize,N_RB,dci_alloc->size-pos,*dci_pdu); -#endif - // Time domain assignment - pos+=4; - *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"time-domain assignment %d (3 bits)=> %d (0x%lx)\n",pdu_rel15->time_domain_assignment,dci_alloc->size-pos,*dci_pdu); -#endif - // VRB to PRB mapping - - pos++; - *dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&0x1)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n",pdu_rel15->vrb_to_prb_mapping,dci_alloc->size-pos,*dci_pdu); -#endif - // MCS - pos+=5; - *dci_pdu |= ((uint64_t)pdu_rel15->mcs&0x1f)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"mcs %d (5 bits)=> %d (0x%lx)\n",pdu_rel15->mcs,dci_alloc->size-pos,*dci_pdu); -#endif - // TB scaling - pos+=2; - *dci_pdu |= ((uint64_t)pdu_rel15->tb_scaling&0x3)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",pdu_rel15->tb_scaling,dci_alloc->size-pos,*dci_pdu); -#endif - break; - - case NFAPI_NR_RNTI_C: - - // indicating a DL DCI format 1bit - pos++; - *dci_pdu |= ((uint64_t)pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",pdu_rel15->format_indicator,1,N_RB,dci_alloc->size-pos,*dci_pdu); -#endif - - // Freq domain assignment (275rb >> fsize = 16) - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - pos+=fsize; - *dci_pdu |= (((uint64_t)pdu_rel15->frequency_domain_assignment&((1< size-pos)); - -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"Freq domain assignment %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->frequency_domain_assignment,fsize,dci_alloc->size-pos,*dci_pdu); -#endif - - uint16_t is_ra = 1; - for (int i=0; i frequency_domain_assignment>>i)&1)) { - is_ra = 0; - break; + int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->RNTI[i],gNB,SEARCH_EXIST_OR_FREE); + if( (dlsch_id<0) || (dlsch_id>=NUMBER_OF_NR_DLSCH_MAX) ){ + LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->RNTI[i],dlsch_id); + return; } - if (is_ra) //fsize are all 1 38.212 p86 - { - // ra_preamble_index 6 bits - pos+=6; - *dci_pdu |= ((pdu_rel15->ra_preamble_index&0x3f)<<(dci_alloc->size-pos)); - - // UL/SUL indicator 1 bit - pos++; - *dci_pdu |= (pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos); - - // SS/PBCH index 6 bits - pos+=6; - *dci_pdu |= ((pdu_rel15->ss_pbch_index&0x3f)<<(dci_alloc->size-pos)); - - // prach_mask_index 4 bits - pos+=4; - *dci_pdu |= ((pdu_rel15->prach_mask_index&0xf)<<(dci_alloc->size-pos)); - - } //end if - - else { - - // Time domain assignment 4bit - - pos+=4; - *dci_pdu |= ((pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"Time domain assignment %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->time_domain_assignment,4,dci_alloc->size-pos,*dci_pdu); -#endif - - // VRB to PRB mapping 1bit - pos++; - *dci_pdu |= (pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"VRB to PRB %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->vrb_to_prb_mapping,1,dci_alloc->size-pos,*dci_pdu); -#endif - - // MCS 5bit //bit over 32, so dci_pdu ++ - pos+=5; - *dci_pdu |= (pdu_rel15->mcs&0x1f)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"MCS %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->mcs,5,dci_alloc->size-pos,*dci_pdu); -#endif - - // New data indicator 1bit - pos++; - *dci_pdu |= (pdu_rel15->ndi&1)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"NDI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->ndi,1,dci_alloc->size-pos,*dci_pdu); -#endif - - // Redundancy version 2bit - pos+=2; - *dci_pdu |= (pdu_rel15->rv&0x3)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"RV %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->rv,2,dci_alloc->size-pos,*dci_pdu); -#endif - - // HARQ process number 4bit - pos+=4; - *dci_pdu |= ((pdu_rel15->harq_pid&0xf)<<(dci_alloc->size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->harq_pid,4,dci_alloc->size-pos,*dci_pdu); -#endif - - // Downlink assignment index 2bit - pos+=2; - *dci_pdu |= ((pdu_rel15->dai&3)<<(dci_alloc->size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"DAI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->dai,2,dci_alloc->size-pos,*dci_pdu); -#endif - - // TPC command for scheduled PUCCH 2bit - pos+=2; - *dci_pdu |= ((pdu_rel15->tpc&3)<<(dci_alloc->size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"TPC %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->tpc,2,dci_alloc->size-pos,*dci_pdu); -#endif - - // PUCCH resource indicator 3bit - pos+=3; - *dci_pdu |= ((pdu_rel15->pucch_resource_indicator&0x7)<<(dci_alloc->size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"PUCCH RI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->pucch_resource_indicator,3,dci_alloc->size-pos,*dci_pdu); -#endif - - // PDSCH-to-HARQ_feedback timing indicator 3bit - pos+=3; - *dci_pdu |= ((pdu_rel15->pdsch_to_harq_feedback_timing_indicator&0x7)<<(dci_alloc->size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"PDSCH to HARQ TI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->pdsch_to_harq_feedback_timing_indicator,3,dci_alloc->size-pos,*dci_pdu); -#endif - - } //end else - break; - - case NFAPI_NR_RNTI_P: - - // Short Messages Indicator – 2 bits - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->short_messages_indicator>>(1-i))&1)<<(dci_alloc->size-pos++); - // Short Messages – 8 bits - for (int i=0; i<8; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->short_messages>>(7-i))&1)<<(dci_alloc->size-pos++); - // Freq domain assignment 0-16 bit - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - for (int i=0; i frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++); - // Time domain assignment 4 bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++); - // VRB to PRB mapping 1 bit - *dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++); - // MCS 5 bit - for (int i=0; i<5; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++); - - // TB scaling 2 bit - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->tb_scaling>>(1-i))&1)<<(dci_alloc->size-pos++); - - - break; - - case NFAPI_NR_RNTI_SI: - // Freq domain assignment 0-16 bit - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - for (int i=0; i frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++); - // Time domain assignment 4 bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++); - // VRB to PRB mapping 1 bit - *dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++); - // MCS 5bit //bit over 32, so dci_pdu ++ - for (int i=0; i<5; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++); - // Redundancy version 2bit - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++); - - break; - - case NFAPI_NR_RNTI_TC: - // indicating a DL DCI format 1bit - *dci_pdu |= ((uint64_t)pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++); - // Freq domain assignment 0-16 bit - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - for (int i=0; i frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++); - // Time domain assignment 4 bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++); - // VRB to PRB mapping 1 bit - *dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++); - // MCS 5bit //bit over 32, so dci_pdu ++ - for (int i=0; i<5; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++); - // New data indicator 1bit - *dci_pdu |= ((uint64_t)pdu_rel15->ndi&1)<<(dci_alloc->size-pos++); - // Redundancy version 2bit - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++); - // HARQ process number 4bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++); - - // Downlink assignment index – 2 bits - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->dai>>(1-i))&1)<<(dci_alloc->size-pos++); - // TPC command for scheduled PUCCH – 2 bits - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++); + dlsch = gNB->dlsch[dlsch_id][0]; + int harq_pid = 0;//extract_harq_pid(i,pdu_rel15); + dlsch->slot_tx[slot] = 1; + dlsch->harq_ids[frame%2][slot] = harq_pid; + AssertFatal(harq_pid < 8 && harq_pid >= 0, + "illegal harq_pid %d\n",harq_pid); + + dlsch->harq_mask |= (1< rnti = pdcch_pdu_rel15->RNTI[i]; + + nr_fill_cce_list(gNB,0); + /* + LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]); + LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx); + */ + + } + +} +void nr_fill_ul_dci(PHY_VARS_gNB *gNB, + int frame, + int slot) { + + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &gNB->ul_dci_pdu->pdcch_pdu.pdcch_pdu_rel15; + + + for (int i=0;i numDlDci;i++) { + + uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i]; + + // if there's no DL DCI then generate CCE list + if (gNB->pdcch_pdu) nr_fill_cce_list(gNB,0); + /* + LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]); + LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx); + */ - // LOG_D(PHY, "DCI PDU: [0]->0x%08llx \t [1]->0x%08llx \t [2]->0x%08llx \t [3]->0x%08llx\n", - // dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]); - - - // PDSCH-to-HARQ_feedback timing indicator – 3 bits - for (int i=0; i<3; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->pdsch_to_harq_feedback_timing_indicator>>(2-i))&1)<<(dci_alloc->size-pos++); - - break; - } - break; - - case NFAPI_NR_UL_DCI_FORMAT_0_0: - switch(params_rel15->rnti_type) - { - case NFAPI_NR_RNTI_C: - // indicating a DL DCI format 1bit - *dci_pdu |= ((uint64_t)pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++); - // Freq domain assignment max 16 bit - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - for (int i=0; i frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++); - // Time domain assignment 4bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++); - // Frequency hopping flag – 1 bit - *dci_pdu |= ((uint64_t)pdu_rel15->frequency_hopping_flag&1)<<(dci_alloc->size-pos++); - // MCS 5 bit - for (int i=0; i<5; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++); - // New data indicator 1bit - *dci_pdu |= ((uint64_t)pdu_rel15->ndi&1)<<(dci_alloc->size-pos++); - // Redundancy version 2bit - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++); - // HARQ process number 4bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++); - - // TPC command for scheduled PUSCH – 2 bits - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++); - - // Padding bits - for(int a = pos;a<32;a++) - *dci_pdu |= ((uint64_t)pdu_rel15->padding&1)<<(dci_alloc->size-pos++); - - // UL/SUL indicator – 1 bit - if (cfg->pucch_config.pucch_GroupHopping.value) - *dci_pdu |= ((uint64_t)pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos++); - - break; - - case NFAPI_NR_RNTI_TC: - - // indicating a DL DCI format 1bit - *dci_pdu |= (pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++); - // Freq domain assignment max 16 bit - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - for (int i=0; i frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++); - // Time domain assignment 4bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++); - // Frequency hopping flag – 1 bit - *dci_pdu |= ((uint64_t)pdu_rel15->frequency_hopping_flag&1)<<(dci_alloc->size-pos++); - // MCS 5 bit - for (int i=0; i<5; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++); - // New data indicator 1bit - *dci_pdu |= ((uint64_t)pdu_rel15->ndi&1)<<(dci_alloc->size-pos++); - // Redundancy version 2bit - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++); - // HARQ process number 4bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++); - - // TPC command for scheduled PUSCH – 2 bits - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++); - - // Padding bits - for(int a = pos;a<32;a++) - *dci_pdu |= ((uint64_t)pdu_rel15->padding&1)<<(dci_alloc->size-pos++); - - // UL/SUL indicator – 1 bit - if (cfg->pucch_config.pucch_GroupHopping.value) - *dci_pdu |= ((uint64_t)pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos++); - - break; - } - break; } - LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]); - LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx); - } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools_common.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools_common.c new file mode 100644 index 0000000000..d26a52f157 --- /dev/null +++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools_common.c @@ -0,0 +1,62 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/NR_TRANSPORT/nr_dci_tools_common.c + * \brief + * \author + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: + * \note + * \warning + */ + +#include "nr_dci.h" + +//#define DEBUG_FILL_DCI + +#include "nr_dlsch.h" + + +void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) { + + uint8_t count=0, start=0, start_set=0; + + uint64_t bitmap = (((uint64_t)FreqDomainResource[0])<<37)| + (((uint64_t)FreqDomainResource[1])<<29)| + (((uint64_t)FreqDomainResource[2])<<21)| + (((uint64_t)FreqDomainResource[3])<<13)| + (((uint64_t)FreqDomainResource[4])<<5)| + (((uint64_t)FreqDomainResource[5])>>3); + + for (int i=0; i<45; i++) + if ((bitmap>>(44-i))&1) { + count++; + if (!start_set) { + start = i; + start_set = 1; + } + } + *rb_offset = 6*start; + *n_rb = 6*count; +} + diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 31d321f01c..4518280f6b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -39,11 +39,11 @@ //#define DEBUG_DLSCH_MAPPING void nr_pdsch_codeword_scrambling(uint8_t *in, - uint16_t size, - uint8_t q, - uint32_t Nid, - uint32_t n_RNTI, - uint32_t* out) { + uint32_t size, + uint8_t q, + uint32_t Nid, + uint32_t n_RNTI, + uint32_t* out) { uint8_t reset, b_idx; uint32_t x1, x2, s=0; @@ -65,174 +65,230 @@ void nr_pdsch_codeword_scrambling(uint8_t *in, } +void nr_pdsch_codeword_scrambling_optim(uint8_t *in, + uint32_t size, + uint8_t q, + uint32_t Nid, + uint32_t n_RNTI, + uint32_t* out) { + + uint32_t x1, x2, s=0,in32; + + x2 = (n_RNTI<<15) + (q<<14) + Nid; + + s=lte_gold_generic(&x1, &x2, 1); + +#if defined(__AVX2__) + for (int i=0; i<((size>>5)+((size&0x1f) > 0 ? 1 : 0)); i++) { + in32=_mm256_movemask_epi8(_mm256_slli_epi16(((__m256i*)in)[i],7)); + out[i]=(in32^s); + // printf("in[%d] %x => %x\n",i,in32,out[i]); + s=lte_gold_generic(&x1, &x2, 0); + } +#elif defined(__SSE4__) + _m128i *in128; + for (int i=0; i<((size>>5)+((size&0x1f) > 0 ? 1 : 0)); i++) { + in128=&((__m128i*)in)[i<<1]; + ((uint16_t*)&in32)[0] = _mm128_movemask_epi8(_mm256_slli_epi16(in128[0],7)); + ((uint16_t*)&in32)[1] = _mm128_movemask_epi8(_mm256_slli_epi16(in128[1],7)); + out[i]=(in32^s); + s=lte_gold_generic(&x1, &x2, 0); + } + //#elsif defined(__arm__) || defined(__aarch64) + +#else + nr_pdsch_codeword_scrambling(in, + size, + q, + Nid, + n_RNTI, + out); +#endif +} + uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch, - NR_gNB_DCI_ALLOC_t *dci_alloc, uint32_t ***pdsch_dmrs, int32_t** txdataF, int16_t amp, int frame, uint8_t slot, NR_DL_FRAME_PARMS *frame_parms, - nfapi_nr_config_request_t *config, + int xOverhead, time_stats_t *dlsch_encoding_stats, time_stats_t *dlsch_scrambling_stats, - time_stats_t *dlsch_modulation_stats) { + time_stats_t *dlsch_modulation_stats, + time_stats_t *tinput, + time_stats_t *tprep, + time_stats_t *tparity, + time_stats_t *toutput, + time_stats_t *dlsch_rate_matching_stats, + time_stats_t *dlsch_interleaving_stats, + time_stats_t *dlsch_segmentation_stats) { - NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[dci_alloc->harq_pid]; - nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &harq->dlsch_pdu.dlsch_pdu_rel15; - nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc->pdcch_params; + int harq_pid = 0; + NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[harq_pid]; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs; int16_t **tx_layers = (int16_t**)dlsch->txdataF; int8_t Wf[2], Wt[2], l0, l_prime[2], delta; - uint16_t nb_symbols = rel15->nb_mod_symbols; - uint8_t Qm = rel15->modulation_order; - uint16_t encoded_length = nb_symbols*Qm; + + uint8_t dmrs_Type = rel15->dmrsConfigType; + int nb_re_dmrs = (dmrs_Type== NFAPI_NR_DMRS_TYPE1) ? 6:4; + uint16_t n_dmrs = ((rel15->rbSize+rel15->rbStart)*nb_re_dmrs)<<1; + int16_t mod_dmrs[n_dmrs<<1]; + + uint16_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords; + uint8_t Qm = rel15->qamModOrder[0]; + uint32_t encoded_length = nb_re*Qm; /// CRC, coding, interleaving and rate matching AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n"); start_meas(dlsch_encoding_stats); - nr_dlsch_encoding(harq->pdu, frame, slot, dlsch, frame_parms); + nr_dlsch_encoding(harq->pdu, frame, slot, dlsch, frame_parms,tinput,tprep,tparity,toutput, + dlsch_rate_matching_stats, + dlsch_interleaving_stats, + dlsch_segmentation_stats); stop_meas(dlsch_encoding_stats); #ifdef DEBUG_DLSCH -printf("PDSCH encoding:\nPayload:\n"); -for (int i=0; i B>>7; i++) { - for (int j=0; j<16; j++) - printf("0x%02x\t", harq->pdu[(i<<4)+j]); + printf("PDSCH encoding:\nPayload:\n"); + for (int i=0; i B>>7; i++) { + for (int j=0; j<16; j++) + printf("0x%02x\t", harq->pdu[(i<<4)+j]); + printf("\n"); + } + printf("\nEncoded payload:\n"); + for (int i=0; i >3; i++) { + for (int j=0; j<8; j++) + printf("%d", harq->f[(i<<3)+j]); + printf("\t"); + } printf("\n"); -} -printf("\nEncoded payload:\n"); -for (int i=0; i >3; i++) { - for (int j=0; j<8; j++) - printf("%d", harq->f[(i<<3)+j]); - printf("\t"); -} -printf("\n"); #endif + + /// scrambling start_meas(dlsch_scrambling_stats); - for (int q=0; q nb_codewords; q++) + for (int q=0; q NrOfCodewords; q++) memset((void*)scrambled_output[q], 0, (encoded_length>>5)*sizeof(uint32_t)); - uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? \ - ((pdcch_params.scrambling_id==0)?pdcch_params.rnti:0) : 0; - uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? \ - pdcch_params.scrambling_id : config->sch_config.physical_cell_id.value; - for (int q=0; q nb_codewords; q++) - nr_pdsch_codeword_scrambling(harq->f, - encoded_length, - q, - Nid, - n_RNTI, - scrambled_output[q]); + for (int q=0; q NrOfCodewords; q++) + nr_pdsch_codeword_scrambling_optim(harq->f, + encoded_length, + q, + rel15->dlDmrsScramblingId, + rel15->rnti, + scrambled_output[q]); + stop_meas(dlsch_scrambling_stats); #ifdef DEBUG_DLSCH -printf("PDSCH scrambling:\n"); -for (int i=0; i >8; i++) { - for (int j=0; j<8; j++) - printf("0x%08x\t", scrambled_output[0][(i<<3)+j]); - printf("\n"); -} + printf("PDSCH scrambling:\n"); + for (int i=0; i >8; i++) { + for (int j=0; j<8; j++) + printf("0x%08x\t", scrambled_output[0][(i<<3)+j]); + printf("\n"); + } #endif /// Modulation start_meas(dlsch_modulation_stats); - for (int q=0; q nb_codewords; q++) + for (int q=0; q NrOfCodewords; q++) nr_modulation(scrambled_output[q], encoded_length, Qm, mod_symbs[q]); stop_meas(dlsch_modulation_stats); #ifdef DEBUG_DLSCH -printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_symbols); -for (int i=0; i >3; i++) { - for (int j=0; j<8; j++) { - printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]); - } - printf("\n"); -} -#endif - - - /// Layer mapping - nr_layer_mapping(mod_symbs, - rel15->nb_layers, - nb_symbols, - tx_layers); -#ifdef DEBUG_DLSCH -printf("Layer mapping (%d layers):\n", rel15->nb_layers); -for (int l=0; l nb_layers; l++) - for (int i=0; i<(nb_symbols/rel15->nb_layers)>>3; i++) { + printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_re); + for (int i=0; i >3; i++) { for (int j=0; j<8; j++) { - printf("%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]); + printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]); } printf("\n"); } #endif - /// Antenna port mapping - //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007 - - /// DMRS QPSK modulation - - int nb_re_dmrs = rel15->dmrs_Type==1?6:4; - uint16_t n_dmrs = (rel15->n_prb*nb_re_dmrs)<<1; - int16_t mod_dmrs[n_dmrs<<1]; - uint8_t dmrs_type = rel15->dmrs_Type; - uint8_t mapping_type = rel15->mapping_type; - - l0 = get_l0(mapping_type, 2);//config->pdsch_config.dmrs_typeA_position.value); - nr_modulation(pdsch_dmrs[l0][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated + /// Layer mapping + nr_layer_mapping(mod_symbs, + rel15->nrOfLayers, + nb_re, + tx_layers); #ifdef DEBUG_DLSCH -printf("DMRS modulation (single symbol %d, %d symbols, type %d):\n", l0, n_dmrs>>1, dmrs_type); -for (int i=0; i >4; i++) { - for (int j=0; j<8; j++) { - printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]); - } - printf("\n"); -} + printf("Layer mapping (%d layers):\n", rel15->nrOfLayers); + for (int l=0; l nrOfLayers; l++) + for (int i=0; i<(nb_re/rel15->nrOfLayers)>>3; i++) { + printf("layer %d, Re %d..%d : ",l,i<<3,(i<<3)+7); + for (int j=0; j<8; j++) { + printf("l%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]); + } + printf("\n"); + } #endif - + /// Antenna port mapping + //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007 + + /// DMRS QPSK modulation + + + l0 = get_l0(rel15->dlDmrsSymbPos); + nr_modulation(pdsch_dmrs[l0][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated + +#ifdef DEBUG_DLSCH + printf("DMRS modulation (single symbol %d, %d symbols, type %d):\n", l0, n_dmrs>>1, dmrs_Type); + for (int i=0; i >4; i++) { + for (int j=0; j<8; j++) { + printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]); + } + printf("\n"); + } +#endif + + /// Resource mapping - + // Non interleaved VRB to PRB mapping - uint16_t start_sc = frame_parms->first_carrier_offset + rel15->start_prb*NR_NB_SC_PER_RB; + uint16_t start_sc = frame_parms->first_carrier_offset + rel15->rbStart*NR_NB_SC_PER_RB; if (start_sc >= frame_parms->ofdm_symbol_size) start_sc -= frame_parms->ofdm_symbol_size; #ifdef DEBUG_DLSCH_MAPPING - printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_symbols %d)\n", - start_sc, rel15->start_symbol, rel15->n_prb, rel15->nb_symbols); + printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n", + start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers); #endif - - for (int ap=0; ap nb_layers; ap++) { + for (int ap=0; ap nrOfLayers; ap++) { // DMRS params for this ap - get_Wt(Wt, ap, dmrs_type); - get_Wf(Wf, ap, dmrs_type); - delta = get_delta(ap, dmrs_type); + get_Wt(Wt, ap, dmrs_Type); + get_Wf(Wf, ap, dmrs_Type); + delta = get_delta(ap, dmrs_Type); l_prime[0] = 0; // single symbol ap 0 uint8_t dmrs_symbol = l0+l_prime[0]; #ifdef DEBUG_DLSCH_MAPPING -printf("DMRS params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n", -ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol); + printf("DMRS Type %d params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n", + 1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol); #endif uint8_t k_prime=0; uint16_t m=0, n=0, dmrs_idx=0, k=0; - for (int l=rel15->start_symbol; l start_symbol+rel15->nb_symbols; l++) { + int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP; + if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k) + dmrs_idx = rel15->rbStart*6; + else + dmrs_idx = rel15->rbStart*4; + + for (int l=rel15->StartSymbolIndex; l StartSymbolIndex+rel15->NrOfSymbols; l++) { k = start_sc; - for (int i=0; i n_prb*NR_NB_SC_PER_RB; i++) { - if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_type))%(frame_parms->ofdm_symbol_size)))) { - ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; + for (int i=0; i rbSize*NR_NB_SC_PER_RB; i++) { + if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) { + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; #ifdef DEBUG_DLSCH_MAPPING -printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", -dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1], -((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1]); + printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", + dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif dmrs_idx++; k_prime++; @@ -242,12 +298,12 @@ dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_ else { - ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * tx_layers[ap][m<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; #ifdef DEBUG_DLSCH_MAPPING -printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", -m, l, k, ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1], -((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1]); + printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", +m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif m++; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h index d4a08c5719..d4c12a0ac8 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h @@ -36,10 +36,10 @@ #include "PHY/defs_gNB.h" void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config, - nfapi_nr_dl_config_dci_dl_pdu dci_pdu, - nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu); + nfapi_nr_dl_tti_pdcch_pdu dci_pdu, + nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu); -void nr_check_time_alloc(uint8_t S, uint8_t L,nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15,nfapi_nr_config_request_t *cfg); +void nr_check_time_alloc(uint8_t S, uint8_t L,nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,nfapi_nr_config_request_t *cfg); uint16_t get_RIV(uint16_t rb_start, uint16_t L, uint16_t N_RB); @@ -51,41 +51,45 @@ void nr_get_rbg_parms(NR_BWP_PARMS* bwp, uint8_t config_type); void nr_get_rbg_list(uint32_t bitmap, uint8_t n_rbg, uint8_t* rbg_list); -void nr_get_PRG_parms(NR_BWP_PARMS* bwp, NR_gNB_DCI_ALLOC_t dci_alloc, uint8_t prb_bundling_type); - uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx); uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx); void nr_pdsch_codeword_scrambling(uint8_t *in, - uint16_t size, - uint8_t q, - uint32_t Nid, - uint32_t n_RNTI, - uint32_t* out); + uint32_t size, + uint8_t q, + uint32_t Nid, + uint32_t n_RNTI, + uint32_t* out); void nr_fill_dlsch(PHY_VARS_gNB *gNB, int frame, int slot, - nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, + nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, unsigned char *sdu); uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch, - NR_gNB_DCI_ALLOC_t *dci_alloc, uint32_t ***pdsch_dmrs, int32_t** txdataF, int16_t amp, int frame, uint8_t slot, NR_DL_FRAME_PARMS *frame_parms, - nfapi_nr_config_request_t *config, + int xOverhead, time_stats_t *dlsch_encoding_stats, time_stats_t *dlsch_scrambling_stats, - time_stats_t *dlsch_modulation_stats); + time_stats_t *dlsch_modulation_stats, + time_stats_t *tinput, + time_stats_t *tprep, + time_stats_t *tparity, + time_stats_t *toutput, + time_stats_t *dlsch_rate_matching_stats, + time_stats_t *dlsch_interleaving_stats, + time_stats_t *dlsch_segmentation_stats); -void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch); +void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch,uint16_t N_RB); void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch); @@ -94,9 +98,16 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch); int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type); int nr_dlsch_encoding(unsigned char *a,int frame, - uint8_t slot, - NR_gNB_DLSCH_t *dlsch, - NR_DL_FRAME_PARMS* frame_parms); + uint8_t slot, + NR_gNB_DLSCH_t *dlsch, + NR_DL_FRAME_PARMS* frame_parms, + time_stats_t *tinput, + time_stats_t *tprep, + time_stats_t *tparity, + time_stats_t *toutput, + time_stats_t *dlsch_rate_matching_stats, + time_stats_t *dlsch_interleaving_stats, + time_stats_t *dlsch_segmentation_stats); void nr_emulate_dlsch_payload(uint8_t* payload, uint16_t size); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 7fd68d5fa9..bd469edcfe 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -39,6 +39,7 @@ #include "PHY/NR_TRANSPORT/nr_transport.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" +#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" #include "SCHED_NR/sched_nr.h" #include "defs.h" #include "common/utils/LOG/vcd_signal_dumper.h" @@ -48,12 +49,22 @@ //#define DEBUG_DLSCH_CODING //#define DEBUG_DLSCH_FREE 1 -void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) +void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch,uint16_t N_RB) { int i; int r; + uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated if (dlsch) { + + if (N_RB != 273) { + a_segments = a_segments*N_RB; + a_segments = a_segments/273; + } + + uint16_t dlsch_bytes = a_segments*1056; // allocated bytes per segment + + #ifdef DEBUG_DLSCH_FREE LOG_D(PHY,"Freeing dlsch %p\n",dlsch); #endif @@ -69,18 +80,34 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) #endif if (dlsch->harq_processes[i]->b) { - free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES); //this should be MAX_NR_DLSCH_PAYLOAD_BYTES + free16(dlsch->harq_processes[i]->b,dlsch_bytes); dlsch->harq_processes[i]->b = NULL; #ifdef DEBUG_DLSCH_FREE LOG_D(PHY,"Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b); #endif } + if (dlsch->harq_processes[i]->e) { + free16(dlsch->harq_processes[i]->e,14*N_RB*12*8); + dlsch->harq_processes[i]->e = NULL; +#ifdef DEBUG_DLSCH_FREE + printf("Freeing dlsch process %d e (%p)\n",i,dlsch->harq_processes[i]->e); +#endif + } + + if (dlsch->harq_processes[i]->f) { + free16(dlsch->harq_processes[i]->f,14*N_RB*12*8); + dlsch->harq_processes[i]->f = NULL; +#ifdef DEBUG_DLSCH_FREE + printf("Freeing dlsch process %d f (%p)\n",i,dlsch->harq_processes[i]->f); +#endif + } + #ifdef DEBUG_DLSCH_FREE LOG_D(PHY,"Freeing dlsch process %d c (%p)\n",i,dlsch->harq_processes[i]->c); #endif - for (r=0; r harq_processes[i]->c[r]); @@ -95,7 +122,7 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) dlsch->harq_processes[i]->d[r] = NULL; } - } + } free16(dlsch->harq_processes[i],sizeof(NR_DL_gNB_HARQ_t)); dlsch->harq_processes[i] = NULL; } @@ -103,35 +130,31 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) free16(dlsch,sizeof(NR_gNB_DLSCH_t)); dlsch = NULL; - } + } } -NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo, +NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, + unsigned char Kmimo, unsigned char Mdlharq, uint32_t Nsoft, - uint8_t abstraction_flag, - NR_DL_FRAME_PARMS *frame_parms, - nfapi_nr_config_request_t *config) + uint8_t abstraction_flag, + uint16_t N_RB) { NR_gNB_DLSCH_t *dlsch; unsigned char exit_flag = 0,i,r,aa,layer; int re; - unsigned char bw_scaling =1; - uint16_t N_RB = config->rf_config.dl_carrier_bandwidth.value; + uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated - switch (N_RB) { + if (N_RB != 273) { + a_segments = a_segments*N_RB; + a_segments = a_segments/273; + } - case 106: - bw_scaling =2; - break; - - default: - bw_scaling =1; - break; - } + uint16_t dlsch_bytes = a_segments*1056; // allocated bytes per segment + dlsch = (NR_gNB_DLSCH_t *)malloc16(sizeof(NR_gNB_DLSCH_t)); if (dlsch) { @@ -144,12 +167,12 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo, for (layer=0; layer ue_spec_bf_weights[layer] = (int32_t**)malloc16(64*sizeof(int32_t*)); - for (aa=0; aa<64; aa++) { + for (aa=0; aa<64; aa++) { dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t)); for (re=0;re ue_spec_bf_weights[layer][aa][re] = 0x00007fff; } - } + } dlsch->txdataF[layer] = (int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH/NR_MAX_NB_LAYERS)*sizeof(int32_t)); // NR_MAX_NB_LAYERS is already included in NR_MAX_PDSCH_ENCODED_LENGTH } @@ -170,31 +193,31 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo, for (i=0; i harq_processes[i] = (NR_DL_gNB_HARQ_t *)malloc16(sizeof(NR_DL_gNB_HARQ_t)); - LOG_T(PHY, "Required mem size %d (bw scaling %d), dlsch->harq_processes[%d] %p\n", - MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling,bw_scaling, i,dlsch->harq_processes[i]); + LOG_T(PHY, "Required mem size %d dlsch->harq_processes[%d] %p\n", + dlsch_bytes, i,dlsch->harq_processes[i]); if (dlsch->harq_processes[i]) { bzero(dlsch->harq_processes[i],sizeof(NR_DL_gNB_HARQ_t)); // dlsch->harq_processes[i]->first_tx=1; - dlsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling); - dlsch->harq_processes[i]->pdu = (uint8_t*)malloc16(MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling); + dlsch->harq_processes[i]->b = (unsigned char*)malloc16(dlsch_bytes); + dlsch->harq_processes[i]->pdu = (uint8_t*)malloc16(dlsch_bytes); if (dlsch->harq_processes[i]->pdu) { - bzero(dlsch->harq_processes[i]->pdu,MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling); - nr_emulate_dlsch_payload(dlsch->harq_processes[i]->pdu, (MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling)>>3); + bzero(dlsch->harq_processes[i]->pdu,dlsch_bytes); + nr_emulate_dlsch_payload(dlsch->harq_processes[i]->pdu, (dlsch_bytes)>>3); } else { LOG_D(PHY,"Can't allocate PDU\n"); exit_flag=1; } if (dlsch->harq_processes[i]->b) { - bzero(dlsch->harq_processes[i]->b,MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling); + bzero(dlsch->harq_processes[i]->b,dlsch_bytes); } else { LOG_D(PHY,"Can't get b\n"); exit_flag=1; } if (abstraction_flag==0) { - for (r=0; r harq_processes[i]->e = (uint8_t*)malloc16(14*N_RB*12*8); + if (dlsch->harq_processes[i]->e) { + bzero(dlsch->harq_processes[i]->e,14*N_RB*12*8); + } else { + printf("Can't get e\n"); + exit_flag=1; + } + dlsch->harq_processes[i]->f = (uint8_t*)malloc16(14*N_RB*12*8); + if (dlsch->harq_processes[i]->f) { + bzero(dlsch->harq_processes[i]->f,14*N_RB*12*8); + } else { + printf("Can't get f\n"); + exit_flag=1; + } } } else { LOG_D(PHY,"Can't get harq_p %d\n",i); @@ -232,7 +269,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo, LOG_D(PHY,"new_gNB_dlsch exit flag %d, size of %ld\n", exit_flag, sizeof(NR_gNB_DLSCH_t)); - free_gNB_dlsch(dlsch); + free_gNB_dlsch(dlsch,N_RB); return(NULL); @@ -260,7 +297,7 @@ void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) dlsch->harq_processes[i]->round = 0; for (j=0; j<96; j++) - for (r=0; r harq_processes[i]->d[r]) dlsch->harq_processes[i]->d[r][j] = NR_NULL; @@ -269,94 +306,111 @@ void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) } } -int nr_dlsch_encoding(unsigned char *a,int frame, - uint8_t slot, - NR_gNB_DLSCH_t *dlsch, - NR_DL_FRAME_PARMS* frame_parms) +int nr_dlsch_encoding(unsigned char *a, + int frame, + uint8_t slot, + NR_gNB_DLSCH_t *dlsch, + NR_DL_FRAME_PARMS* frame_parms, + time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput, + time_stats_t *dlsch_rate_matching_stats,time_stats_t *dlsch_interleaving_stats, + time_stats_t *dlsch_segmentation_stats) { unsigned int G; unsigned int crc=1; - uint8_t harq_pid = dlsch->harq_ids[frame&2][slot]; + uint8_t harq_pid = dlsch->harq_ids[frame%2][slot]; AssertFatal(harq_pid<8 && harq_pid>=0,"illegal harq_pid %d\b",harq_pid); - nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; - uint16_t nb_rb = rel15->n_prb; - uint8_t nb_symb_sch = rel15->nb_symbols; - uint32_t A, Z, F=0; - uint32_t *pz = &Z; - uint8_t mod_order = rel15->modulation_order; - uint16_t Kr=0,r,r_offset=0; - //uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS]; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->pdsch_pdu.pdsch_pdu_rel15; + uint16_t nb_rb = rel15->rbSize; + uint8_t nb_symb_sch = rel15->NrOfSymbols; + uint32_t A, Z, Kb, F=0; + uint32_t *Zc = &Z; + uint8_t mod_order = rel15->qamModOrder[0]; + uint16_t Kr=0,r; + uint32_t r_offset=0; uint8_t BG=1; uint32_t E; - uint8_t Ilbrm = 0; + uint8_t Ilbrm = 1; uint32_t Tbslbrm = 950984; //max tbs - uint8_t nb_re_dmrs = rel15->dmrs_Type==1 ? 6:4; - uint16_t length_dmrs = rel15->dmrs_maxLength; + uint8_t nb_re_dmrs = rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1 ? 6:4; + uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos); + uint16_t R=rel15->targetCodeRate[0]; float Coderate = 0.0; + uint8_t Nl = 4; - /* - uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS]; //unsigned char - for(j=0;j transport_block_size; + A = rel15->TBSize[0]<<3; - G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15->nb_layers); + G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15->nrOfLayers); LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order); - - - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, rel15->nb_layers); // if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet #ifdef DEBUG_DLSCH_CODING LOG_D(PHY,"encoding thinks this is a new packet \n"); #endif - /* + /* int i; LOG_D(PHY,"dlsch (tx): \n"); for (i=0;i<(A>>3);i++) - LOG_D(PHY,"%02x.",a[i]); + LOG_D(PHY,"%02x\n",a[i]); LOG_D(PHY,"\n"); - */ - // Add 24-bit crc (polynomial A) to payload - crc = crc24a(a,A)>>8; - a[A>>3] = ((uint8_t*)&crc)[2]; - a[1+(A>>3)] = ((uint8_t*)&crc)[1]; - a[2+(A>>3)] = ((uint8_t*)&crc)[0]; - //LOG_D(PHY,"CRC %x (A %d)\n",crc,A); - //LOG_D(PHY,"a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]); + */ - dlsch->harq_processes[harq_pid]->B = A+24; - // dlsch->harq_processes[harq_pid]->b = a; + if (A > 3824) { + // Add 24-bit crc (polynomial A) to payload + crc = crc24a(a,A)>>8; + a[A>>3] = ((uint8_t*)&crc)[2]; + a[1+(A>>3)] = ((uint8_t*)&crc)[1]; + a[2+(A>>3)] = ((uint8_t*)&crc)[0]; + //printf("CRC %x (A %d)\n",crc,A); + //printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]); + + dlsch->harq_processes[harq_pid]->B = A+24; + // dlsch->harq_processes[harq_pid]->b = a; - AssertFatal((A/8)+4 <= MAX_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_DLSCH_PAYLOAD_BYTES); + AssertFatal((A/8)+4 <= MAX_NR_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_NR_DLSCH_PAYLOAD_BYTES); - memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); + memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); // why is this +4 if the CRC is only 3 bytes? + } + else { + // Add 16-bit crc (polynomial A) to payload + crc = crc16(a,A)>>16; + a[A>>3] = ((uint8_t*)&crc)[1]; + a[1+(A>>3)] = ((uint8_t*)&crc)[0]; + //printf("CRC %x (A %d)\n",crc,A); + //printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]); + + dlsch->harq_processes[harq_pid]->B = A+16; + // dlsch->harq_processes[harq_pid]->b = a; + + AssertFatal((A/8)+3 <= MAX_NR_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,MAX_NR_DLSCH_PAYLOAD_BYTES); - nr_segmentation(dlsch->harq_processes[harq_pid]->b, - dlsch->harq_processes[harq_pid]->c, - dlsch->harq_processes[harq_pid]->B, - &dlsch->harq_processes[harq_pid]->C, - &dlsch->harq_processes[harq_pid]->K, - pz, // [hna] pz is Zc - &dlsch->harq_processes[harq_pid]->F); + memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+3); // using 3 bytes to mimic the case of 24 bit crc + } + if (R<1000) + Coderate = (float) R /(float) 1024; + else // to scale for mcs 20 and 26 in table 5.1.3.1-2 which are decimal and input 2* in nr_tbs_tools + Coderate = (float) R /(float) 2048; - F = dlsch->harq_processes[harq_pid]->F; - Coderate = (float) A /(float) G; - - if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ + if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) BG = 2; - } - else{ + else BG = 1; - } + + start_meas(dlsch_segmentation_stats); + Kb = nr_segmentation(dlsch->harq_processes[harq_pid]->b, + dlsch->harq_processes[harq_pid]->c, + dlsch->harq_processes[harq_pid]->B, + &dlsch->harq_processes[harq_pid]->C, + &dlsch->harq_processes[harq_pid]->K, + Zc, + &dlsch->harq_processes[harq_pid]->F, + BG); + stop_meas(dlsch_segmentation_stats); + F = dlsch->harq_processes[harq_pid]->F; Kr = dlsch->harq_processes[harq_pid]->K; #ifdef DEBUG_DLSCH_CODING @@ -364,7 +418,7 @@ int nr_dlsch_encoding(unsigned char *a,int frame, Kr_bytes = Kr>>3; #endif - //LOG_D(PHY,"segment Z %d k %d Kr %d BG %d\n", *pz,dlsch->harq_processes[harq_pid]->K,Kr,BG); + //printf("segment Z %d k %d Kr %d BG %d C %d\n", *Zc,dlsch->harq_processes[harq_pid]->K,Kr,BG,dlsch->harq_processes[harq_pid]->C); for (r=0; r harq_processes[harq_pid]->C; r++) { //d_tmp[r] = &dlsch->harq_processes[harq_pid]->d[r][0]; @@ -373,30 +427,23 @@ int nr_dlsch_encoding(unsigned char *a,int frame, LOG_D(PHY,"Encoder: B %d F %d \n",dlsch->harq_processes[harq_pid]->B, dlsch->harq_processes[harq_pid]->F); LOG_D(PHY,"start ldpc encoder segment %d/%d\n",r,dlsch->harq_processes[harq_pid]->C); LOG_D(PHY,"input %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->c[r][0], dlsch->harq_processes[harq_pid]->c[r][1], dlsch->harq_processes[harq_pid]->c[r][2],dlsch->harq_processes[harq_pid]->c[r][3], dlsch->harq_processes[harq_pid]->c[r][4]); - for (int cnt =0 ; cnt < 22*(*pz)/8; cnt ++){ + for (int cnt =0 ; cnt < 22*(*Zc)/8; cnt ++){ LOG_D(PHY,"%d ", dlsch->harq_processes[harq_pid]->c[r][cnt]); } LOG_D(PHY,"\n"); #endif - //ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],Kr,BG,0); - //ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],Kr,BG,NULL,NULL,NULL,NULL); + //ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],*Zc,Kb,Kr,BG,0); + //ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],*Zc,Kb,Kr,BG,NULL,NULL,NULL,NULL); } - //for (int i=0;i<68*384;i++) - // LOG_D(PHY,"channel_input[%d]=%d\n",i,channel_input[i]); + for(int j=0;j<((dlsch->harq_processes[harq_pid]->C-1)/8+1);j++) { + ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG, + dlsch->harq_processes[harq_pid]->C,j, + tinput,tprep,tparity,toutput); + } - - /*LOG_D(PHY,"output %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->d[0][0], dlsch->harq_processes[harq_pid]->d[0][1], dlsch->harq_processes[harq_pid]->d[r][2],dlsch->harq_processes[harq_pid]->d[0][3], dlsch->harq_processes[harq_pid]->d[0][4]); - for (int cnt =0 ; cnt < 66*(*pz); cnt ++){ - LOG_D(PHY,"%d \n", dlsch->harq_processes[harq_pid]->d[0][cnt]); - } - LOG_D(PHY,"\n");*/ - - //ldpc_encoder_optim_8seg(dlsch->harq_processes[harq_pid]->c,d_tmp,Kr,BG,dlsch->harq_processes[harq_pid]->C,NULL,NULL,NULL,NULL); - ldpc_encoder_optim_8seg(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,Kr,BG,dlsch->harq_processes[harq_pid]->C,NULL,NULL,NULL,NULL); - #ifdef DEBUG_DLSCH_CODING write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4); write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[0][0],(3*8*Kr_bytes)+12,1,4); @@ -406,48 +453,64 @@ int nr_dlsch_encoding(unsigned char *a,int frame, for (r=0; r harq_processes[harq_pid]->C; r++) { - if (dlsch->harq_processes[harq_pid]->F>0) { - for (int k=(Kr-F-2*(*pz)); k harq_processes[harq_pid]->d[r][k] = NR_NULL; - //if (k<(Kr-F+8)) - //LOG_D(PHY,"r %d filler bits [%d] = %d \n", r,k, dlsch->harq_processes[harq_pid]->d[r][k]); - } - } -#ifdef DEBUG_DLSCH_CODING - LOG_D(PHY,"Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n", - r, - G, - Kr*3, - mod_order,nb_rb); -#endif + if (F>0) { + for (int k=(Kr-F-2*(*Zc)); k harq_processes[harq_pid]->d[r][k] = NR_NULL; + //if (k<(Kr-F+8)) + //printf("r %d filler bits [%d] = %d \n", r,k, dlsch->harq_processes[harq_pid]->d[r][k]); + } + } + + #ifdef DEBUG_DLSCH_CODING - LOG_D(PHY,"rvidx in encoding = %d\n", rel15->redundancy_version); + LOG_D(PHY,"rvidx in encoding = %d\n", rel15->rvIndex[0]); #endif - E = nr_get_E(G, dlsch->harq_processes[harq_pid]->C, mod_order, rel15->nb_layers, r); + E = nr_get_E(G, dlsch->harq_processes[harq_pid]->C, mod_order, rel15->nrOfLayers, r); +#ifdef DEBUG_DLSCH_CODING + printf("Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb %d)...\n", + r, + dlsch->harq_processes[harq_pid]->C, + G, + E, + F, + Kr-F-2*(*Zc), + mod_order,nb_rb); +#endif + + // for tbslbrm calculation according to 5.4.2.1 of 38.212 + if (rel15->nrOfLayers < Nl) + Nl = rel15->nrOfLayers; + + Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl,dlsch->harq_processes[harq_pid]->C); + + start_meas(dlsch_rate_matching_stats); nr_rate_matching_ldpc(Ilbrm, Tbslbrm, BG, - *pz, + *Zc, dlsch->harq_processes[harq_pid]->d[r], dlsch->harq_processes[harq_pid]->e+r_offset, dlsch->harq_processes[harq_pid]->C, - rel15->redundancy_version, + F, + Kr-F-2*(*Zc), + rel15->rvIndex[0], E); - - + stop_meas(dlsch_rate_matching_stats); #ifdef DEBUG_DLSCH_CODING for (int i =0; i<16; i++) LOG_D(PHY,"output ratematching e[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset); #endif - nr_interleaving_ldpc(E, - mod_order, - dlsch->harq_processes[harq_pid]->e+r_offset, - dlsch->harq_processes[harq_pid]->f+r_offset); - + start_meas(dlsch_interleaving_stats); + nr_interleaving_ldpc(E, + mod_order, + dlsch->harq_processes[harq_pid]->e+r_offset, + dlsch->harq_processes[harq_pid]->f+r_offset); + stop_meas(dlsch_interleaving_stats); #ifdef DEBUG_DLSCH_CODING for (int i =0; i<16; i++) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c index 47a8a6d3f0..ff1f841e47 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c @@ -27,6 +27,7 @@ * \company Eurecom * \email: desouza@eurecom.fr * \note + * \warning */ @@ -46,6 +47,7 @@ uint8_t nr_pdsch_default_time_alloc_C_L[15] = {2,2,2,2,2,4,4,4,4,4,7,12,11,6,6}; /// Time domain allocation routines +/* void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config, nfapi_nr_dl_config_dci_dl_pdu dci_pdu, nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu) { @@ -73,9 +75,9 @@ void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config, case NFAPI_NR_RNTI_RA: case NFAPI_NR_RNTI_TC: - /*AssertFatal(dci_alloc.pdcch_params.common_search_space_type == NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1, - "Invalid common search space type %d for RNTI %d, expected %d\n",dci_alloc.pdcch_params.common_search_space_type, - NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1, dci_alloc.rnti_type);*/ + //AssertFatal(dci_alloc.pdcch_params.common_search_space_type == NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1, + //"Invalid common search space type %d for RNTI %d, expected %d\n",dci_alloc.pdcch_params.common_search_space_type, + //NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1, dci_alloc.rnti_type); *alloc_type = (alloc_list_flag) ? NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_ALLOC_LIST : NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A; break; @@ -94,6 +96,7 @@ void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config, } } + uint16_t get_SLIV(uint8_t S, uint8_t L) { return ( (uint16_t)(((L-1)<=7)? (14*(L-1)+S) : (14*(15-L)+(13-S))) ); } @@ -104,7 +107,7 @@ static inline uint8_t get_K0(uint8_t row_idx, uint8_t time_alloc_type) { ((row_idx==6)||(row_idx==7)||(row_idx==15))? 1 : 0); } -/*ideally combine the calculation of L in the same function once the right struct is defined*/ +// ideally combine the calculation of L in the same function once the right struct is defined uint8_t nr_get_S(uint8_t row_idx, uint8_t CP, uint8_t time_alloc_type, uint8_t dmrs_TypeA_Position) { uint8_t idx; @@ -132,6 +135,7 @@ uint8_t nr_get_S(uint8_t row_idx, uint8_t CP, uint8_t time_alloc_type, uint8_t d return 0; // temp warning fix } + void nr_check_time_alloc(uint8_t S, uint8_t L,nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15,nfapi_nr_config_request_t *cfg) { switch (cfg->subframe_config.dl_cyclic_prefix_type.value) { @@ -241,6 +245,7 @@ void nr_get_PRG_parms(NR_BWP_PARMS* bwp, NR_gNB_DCI_ALLOC_t dci_alloc, uint8_t p LOG_I(PHY, "PRG parameters for BWP %d location %d N_RB %d:\n", bwp->bwp_id, bwp->location, bwp->N_RB); LOG_I(PHY, "P_prime %d\t start size %d\t endsize %d\t N_PRG %d\n", prg_parms->P_prime, prg_parms->start_size, prg_parms->end_size, prg_parms->N_PRG); } +*/ /// Payload emulation void nr_emulate_dlsch_payload(uint8_t* pdu, uint16_t size) { @@ -257,7 +262,7 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { AssertFatal(gNB!=NULL,"gNB is null\n"); for (i=0; i dlsch[i]!=NULL,"gNB->dlsch[%d] is null\n",i); - AssertFatal(gNB->dlsch[i]!=NULL,"gNB->dlsch[%d][0] is null\n",i); + AssertFatal(gNB->dlsch[i][0]!=NULL,"gNB->dlsch[%d][0] is null\n",i); LOG_D(PHY,"searching for rnti %x : dlsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->dlsch[i][0]->harq_mask,gNB->dlsch[i][0]->rnti,first_free_index); if ((gNB->dlsch[i][0]->harq_mask >0) && (gNB->dlsch[i][0]->rnti==rnti)) return i; @@ -269,13 +274,33 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { return first_free_index; } +int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { + + uint16_t i; + int16_t first_free_index=-1; + + AssertFatal(gNB!=NULL,"gNB is null\n"); + for (i=0; i ulsch[i]!=NULL,"gNB->ulsch[%d] is null\n",i); + AssertFatal(gNB->ulsch[i][0]!=NULL,"gNB->ulsch[%d][0] is null\n",i); + LOG_D(PHY,"searching for rnti %x : ulsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->ulsch[i][0]->harq_mask,gNB->ulsch[i][0]->rnti,first_free_index); + if ((gNB->ulsch[i][0]->harq_mask >0) && + (gNB->ulsch[i][0]->rnti==rnti)) return i; + else if ((gNB->ulsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i; + } + if (type == SEARCH_EXIST) return -1; + if (first_free_index != -1) + gNB->ulsch[first_free_index][0]->rnti = 0; + return first_free_index; +} + void nr_fill_dlsch(PHY_VARS_gNB *gNB, int frame, int slot, - nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, + nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, uint8_t *sdu) { - nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &dlsch_pdu->dlsch_pdu_rel15; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &pdsch_pdu->pdsch_pdu_rel15; int dlsch_id = find_nr_dlsch(rel15->rnti,gNB,SEARCH_EXIST); AssertFatal( (dlsch_id>=0) && (dlsch_id dlsch[dlsch_id][0]; NR_DL_gNB_HARQ_t **harq = dlsch->harq_processes; /// DLSCH struct - memcpy((void*)&harq[dlsch->harq_ids[frame%2][slot]]->dlsch_pdu, (void*)dlsch_pdu, sizeof(nfapi_nr_dl_config_dlsch_pdu)); + memcpy((void*)&harq[dlsch->harq_ids[frame%2][slot]]->pdsch_pdu, (void*)pdsch_pdu, sizeof(nfapi_nr_dl_tti_pdsch_pdu)); + gNB->num_pdsch_rnti++; AssertFatal(sdu!=NULL,"sdu is null\n"); harq[dlsch->harq_ids[frame%2][slot]]->pdu = sdu; } +void nr_fill_ulsch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_pusch_pdu_t *ulsch_pdu) { + + + int ulsch_id = find_nr_ulsch(ulsch_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE); + AssertFatal( (ulsch_id>=0) && (ulsch_id rnti,ulsch_id); + + NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ulsch_id][0]; + int harq_pid = ulsch_pdu->pusch_data.harq_process_id; + ulsch->rnti = ulsch_pdu->rnti; + //ulsch->rnti_type; + ulsch->harq_mask |= 1< harq_process_id[slot] = harq_pid; + + nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch->harq_processes[harq_pid]->ulsch_pdu; + + LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid); + + + //FK this is still a bad hack. We need to replace the L1 FAPI structures with the new scf ones as well. + rel15_ul->rnti = ulsch_pdu->rnti; + rel15_ul->ulsch_pdu_rel15.start_rb = ulsch_pdu->rb_start; + rel15_ul->ulsch_pdu_rel15.number_rbs = ulsch_pdu->rb_size; + rel15_ul->ulsch_pdu_rel15.start_symbol = ulsch_pdu->start_symbol_index; + rel15_ul->ulsch_pdu_rel15.number_symbols = ulsch_pdu->nr_of_symbols; + rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; //where should this come from? + rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; //where should this come from? + rel15_ul->ulsch_pdu_rel15.Qm = ulsch_pdu->qam_mod_order; + rel15_ul->ulsch_pdu_rel15.mcs = ulsch_pdu->mcs_index; + rel15_ul->ulsch_pdu_rel15.rv = ulsch_pdu->pusch_data.rv_index; + rel15_ul->ulsch_pdu_rel15.n_layers = ulsch_pdu->nrOfLayers; + rel15_ul->ulsch_pdu_rel15.R = ulsch_pdu->target_code_rate; + +} + diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c index bb114fa390..c8bdb8beb5 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c @@ -50,13 +50,13 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, - nfapi_nr_config_request_t *config, + nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms) { int k,l; //int16_t a; int16_t mod_dmrs[NR_PBCH_DMRS_LENGTH<<1]; uint8_t idx=0; - uint8_t nushift = config->sch_config.physical_cell_id.value &3; + uint8_t nushift = config->cell_config.phy_cell_id.value &3; LOG_D(PHY, "PBCH DMRS mapping started at symbol %d shift %d\n", ssb_start_symbol+1, nushift); /// QPSK modulation @@ -220,16 +220,15 @@ void nr_init_pbch_interleaver(uint8_t *interleaver) { } int nr_generate_pbch(NR_gNB_PBCH *pbch, - uint8_t *pbch_pdu, + nfapi_nr_dl_tti_ssb_pdu *ssb_pdu, uint8_t *interleaver, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, uint8_t n_hf, uint8_t Lmax, - uint8_t ssb_index, int sfn, - nfapi_nr_config_request_t *config, + nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms) { int k,l,m; //int16_t a; @@ -243,17 +242,18 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ///Payload generation memset((void *)pbch, 0, sizeof(NR_gNB_PBCH)); pbch->pbch_a=0; - + uint8_t ssb_index = ssb_pdu->ssb_pdu_rel15.SsbBlockIndex; + uint8_t *pbch_pdu = (uint8_t*)&ssb_pdu->ssb_pdu_rel15.bchPayload; for (int i=0; i pbch_a |= ((pbch_pdu[2-(i>>3)]>>(7-(i&7)))&1)<pbch_a |= ((pbch_pdu[i>>3]>>(7-(i&7)))&1)<pbch_a); -#endif + #endif // Extra byte generation for (int i=0; i<4; i++) @@ -265,7 +265,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, for (int i=0; i<3; i++) pbch->pbch_a |= ((ssb_index>>(5-i))&1)<<(29+i); // resp. 6th, 5th and 4th bits of ssb_index else - pbch->pbch_a |= ((config->sch_config.ssb_subcarrier_offset.value>>4)&1)<<29; //MSB of k_SSB (bit index 4) + pbch->pbch_a |= ((config->ssb_table.ssb_subcarrier_offset.value>>4)&1)<<29; //MSB of k_SSB (bit index 4) LOG_D(PHY,"After extra byte: pbch_a = 0x%08x\n",pbch->pbch_a); @@ -287,7 +287,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3); nushift = (((sfn>>2)&1)<<1) ^ ((sfn>>1)&1); pbch->pbch_a_prime = 0; - nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS, 0, unscrambling_mask); + nr_pbch_scrambling(pbch, (uint32_t)config->cell_config.phy_cell_id.value, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS, 0, unscrambling_mask); #ifdef DEBUG_PBCH_ENCODING printf("Payload scrambling: nushift %d M %d sfn3 %d sfn2 %d\n", nushift, M, (sfn>>2)&1, (sfn>>1)&1); printf("pbch_a_prime: 0x%08x\n", pbch->pbch_a_prime); @@ -298,8 +298,8 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, a_reversed |= (((uint64_t)pbch->pbch_a_prime>>i)&1)<<(31-i); /// CRC, coding and rate matching - polar_encoder_fast (&a_reversed, (uint32_t *)pbch->pbch_e, 0, - nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL) + polar_encoder_fast (&a_reversed, (uint32_t *)pbch->pbch_e, 0, 0, + nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL,0,NULL) ); #ifdef DEBUG_PBCH_ENCODING printf("Channel coding:\n"); @@ -312,7 +312,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, /// Scrambling M = NR_POLAR_PBCH_E; nushift = (Lmax==4)? ssb_index&3 : ssb_index&7; - nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_E, 1, 0); + nr_pbch_scrambling(pbch, (uint32_t)config->cell_config.phy_cell_id.value, nushift, M, NR_POLAR_PBCH_E, 1, 0); #ifdef DEBUG_PBCH_ENCODING printf("Scrambling:\n"); @@ -333,7 +333,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, } /// Resource mapping - nushift = config->sch_config.physical_cell_id.value &3; + nushift = config->cell_config.phy_cell_id.value &3; // PBCH modulated symbols are mapped within the SSB block on symbols 1, 2, 3 excluding the subcarriers used for the PBCH DMRS ///symbol 1 [0:239] -- 180 mod symbols k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; diff --git a/openair1/PHY/NR_TRANSPORT/nr_pss.c b/openair1/PHY/NR_TRANSPORT/nr_pss.c index e0d7b6ae33..be9e011e60 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pss.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pss.c @@ -28,7 +28,7 @@ int nr_generate_pss( int16_t *d_pss, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, - nfapi_nr_config_request_t* config, + nfapi_nr_config_request_scf_t* config, NR_DL_FRAME_PARMS *frame_parms) { int i,k,l,m; @@ -36,7 +36,7 @@ int nr_generate_pss( int16_t *d_pss, int16_t x[NR_PSS_LENGTH]; const int x_initial[7] = {0, 1, 1 , 0, 1, 1, 1}; - uint8_t Nid2 = config->sch_config.physical_cell_id.value % 3; + uint8_t Nid2 = config->cell_config.phy_cell_id.value % 3; /// Sequence generation for (i=0; i < 7; i++) diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c index 8d9bf00639..ad2edadb5f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c @@ -85,13 +85,19 @@ uint8_t get_delta(uint8_t ap, uint8_t config) { return ((config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][2]):(pdsch_dmrs_2[ap][2])); } -uint16_t get_dmrs_freq_idx(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) { +uint16_t get_dmrs_freq_idx(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) { uint16_t dmrs_idx = (dmrs_type)? (6*n+k_prime+delta):((n<<2)+(k_prime<<1)+delta); return dmrs_idx; } -uint8_t get_l0(uint8_t mapping_type, uint8_t dmrs_typeA_position) { - - return ((mapping_type==NFAPI_NR_PDSCH_MAPPING_TYPE_A)?dmrs_typeA_position:0); +uint8_t get_l0(uint16_t dlDmrsSymbPos) { + uint16_t mask=dlDmrsSymbPos; + int l0; + for (l0=0;l0<14;l0++) { + if ((mask&1) == 1) break; + mask>>=1; + } + AssertFatal(l0 < 4,"impossible l0 %d\n",l0); + return (l0); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h index 02f454b7d0..40cc3fbc1b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h +++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h @@ -45,6 +45,6 @@ void get_Wf(int8_t *Wf, uint8_t ap, uint8_t config); uint8_t get_delta(uint8_t ap, uint8_t config); -uint16_t get_dmrs_freq_idx(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); +uint16_t get_dmrs_freq_idx(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); -uint8_t get_l0(uint8_t mapping_type, uint8_t dmrs_typeA_position); +uint8_t get_l0(uint16_t dlDmrsSymbPos); diff --git a/openair1/PHY/NR_TRANSPORT/nr_sss.c b/openair1/PHY/NR_TRANSPORT/nr_sss.c index 154aca9ffe..7d8b551d7c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sss.c +++ b/openair1/PHY/NR_TRANSPORT/nr_sss.c @@ -27,7 +27,7 @@ int nr_generate_sss( int16_t *d_sss, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, - nfapi_nr_config_request_t* config, + nfapi_nr_config_request_scf_t* config, NR_DL_FRAME_PARMS *frame_parms) { int i,k,l; @@ -39,7 +39,7 @@ int nr_generate_sss( int16_t *d_sss, const int x1_initial[7] = { 1, 0, 0, 0, 0, 0, 0 }; /// Sequence generation - Nid = config->sch_config.physical_cell_id.value; + Nid = config->cell_config.phy_cell_id.value; Nid2 = Nid % 3; Nid1 = (Nid - Nid2)/3; diff --git a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c index 6060a04658..cb85992a8e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c @@ -31,27 +31,7 @@ */ #include "nr_transport_common_proto.h" - - -static inline uint8_t is_codeword_disabled(uint8_t format, uint8_t Imcs, uint8_t rv) { - return ((format==NFAPI_NR_DL_DCI_FORMAT_1_1)&&(Imcs==26)&&(rv==1)); -} - -static inline uint8_t get_table_idx(uint8_t mcs_table, uint8_t dci_format, uint8_t rnti_type, uint8_t ss_type) { - if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM256) && (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_1) && ((rnti_type==NFAPI_NR_RNTI_C)||(rnti_type==NFAPI_NR_RNTI_CS))) - return 2; - else if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM64_LOW_SE) && (rnti_type!=NFAPI_NR_RNTI_new) && (rnti_type==NFAPI_NR_RNTI_C) && (ss_type==NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)) - return 3; - else if (rnti_type==NFAPI_NR_RNTI_new) - return 3; - else if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM256) && (rnti_type==NFAPI_NR_RNTI_CS) && (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_1)) - return 2; // Condition mcs_table not configured in sps_config necessary here but not yet implemented - /*else if((mcs_table == NFAPI_NR_MCS_TABLE_QAM64_LOW_SE) && (rnti_type==NFAPI_NR_RNTI_CS)) - * table_idx = 3; - * Note: the commented block refers to the case where the mcs_table is from sps_config*/ - else - return 1; -} +#include "PHY/CODING/coding_defs.h" uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm, uint8_t Nl) { diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport.h b/openair1/PHY/NR_TRANSPORT/nr_transport.h index d94b73245e..a485351cd3 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport.h @@ -36,7 +36,7 @@ int nr_generate_pss( int16_t *d_pss, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, - nfapi_nr_config_request_t *config, + nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); /*! @@ -49,7 +49,7 @@ int nr_generate_sss( int16_t *d_sss, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, - nfapi_nr_config_request_t *config, + nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); /*! @@ -62,7 +62,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, - nfapi_nr_config_request_t *config, + nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); /*! @@ -85,16 +85,15 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch, @returns 0 on success */ int nr_generate_pbch(NR_gNB_PBCH *pbch, - uint8_t *pbch_pdu, + nfapi_nr_dl_tti_ssb_pdu *ssb_pdu, uint8_t *interleaver, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, uint8_t n_hf, uint8_t Lmax, - uint8_t ssb_index, int sfn, - nfapi_nr_config_request_t *config, + nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); /*! @@ -105,12 +104,12 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, */ void nr_init_pbch_interleaver(uint8_t *interleaver); -NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo, +NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, + unsigned char Kmimo, unsigned char Mdlharq, uint32_t Nsoft, uint8_t abstraction_flag, - NR_DL_FRAME_PARMS *frame_parms, - nfapi_nr_config_request_t *config); + uint16_t N_RB); void rx_nr_prach(PHY_VARS_gNB *gNB, int frame, diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h index 018e36ce4e..762346048f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h @@ -36,20 +36,13 @@ #include "PHY/defs_nr_common.h" -#define MAX_NUM_NR_DLSCH_SEGMENTS 16 -#define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS - #define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1 #define NR_PUSCH_y 3 // UCI placeholder bit -/** \brief Computes Q based on I_MCS PDSCH and table_idx. Implements Table 5.1.3.1-2 from 38.214. */ -uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx); -uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx); -void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, - nfapi_nr_dl_config_dci_dl_pdu dci_pdu); + /** \brief Computes available bits G. */ uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint16_t length_dmrs, uint8_t Qm, uint8_t Nl); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 2dbef1d733..8d220a76bb 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -65,7 +65,9 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, */ void nr_ulsch_extract_rbs_single(int **rxdataF, + int **ul_ch_estimates, int **rxdataF_ext, + int **ul_ch_estimates_ext, uint32_t rxdataF_ext_offset, // unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment unsigned char symbol, @@ -73,6 +75,54 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, unsigned short nb_rb_pusch, NR_DL_FRAME_PARMS *frame_parms); +void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext, + NR_DL_FRAME_PARMS *frame_parms, + NR_gNB_ULSCH_t **ulsch_gNB, + uint8_t symbol, + uint8_t start_symbol, + uint16_t nb_rb); + + +/** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal + @param ul_ch_estimates_ext Channel estimates in allocated RBs + @param frame_parms Pointer to frame descriptor + @param avg Pointer to average signal strength + @param pilots_flag Flag to indicate pilots in symbol + @param nb_rb Number of allocated RBs +*/ +void nr_ulsch_channel_level(int **ul_ch_estimates_ext, + NR_DL_FRAME_PARMS *frame_parms, + int32_t *avg, + uint8_t symbol, + uint32_t len, + unsigned short nb_rb); + + +/** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation) + @param rxdataF_ext Frequency-domain received signal in RBs to be demodulated + @param ul_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated + @param ul_ch_mag First Channel magnitudes (16QAM/64QAM) + @param ul_ch_magb Second weighted Channel magnitudes (64QAM) + @param rxdataF_comp Compensated received waveform + @param frame_parms Pointer to frame descriptor + @param symbol Symbol on which to operate + @param Qm Modulation order of allocation + @param nb_rb Number of RBs in allocation + @param output_shift Rescaling for compensated output (should be energy-normalizing) +*/ +void nr_ulsch_channel_compensation(int **rxdataF_ext, + int **ul_ch_estimates_ext, + int **ul_ch_mag, + int **ul_ch_magb, + int **rxdataF_comp, + int **rho, + NR_DL_FRAME_PARMS *frame_parms, + unsigned char symbol, + uint8_t pilots, + unsigned char mod_order, + unsigned short nb_rb, + unsigned char output_shift); + /*! \brief This function implements the idft transform precoding in PUSCH \param z Pointer to input in frequnecy domain, and it is also the output in time domain @@ -102,6 +152,7 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp, void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, int32_t **ul_ch_mag, int16_t *ulsch_llr, + uint32_t nb_rb, uint32_t nb_re, uint8_t symbol); @@ -118,6 +169,7 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, int32_t **ul_ch_mag, int32_t **ul_ch_magb, int16_t *ulsch_llr, + uint32_t nb_rb, uint32_t nb_re, uint8_t symbol); @@ -135,6 +187,22 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp, int32_t **ul_ch_mag, int32_t **ul_ch_magb, int16_t *ulsch_llr, + uint32_t nb_rb, uint32_t nb_re, uint8_t symbol, - uint8_t mod_order); \ No newline at end of file + uint8_t mod_order); + +void nr_fill_ulsch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_pusch_pdu_t *ulsch_pdu); + +uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx); + +uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx); + +uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx); + +uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx); + +uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h index e7af632327..15e66477c3 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h @@ -1728,41 +1728,6 @@ void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8 uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset); -uint8_t nr_dci_decoding_procedure(int s, - int p, - PHY_VARS_NR_UE *ue, - NR_DCI_ALLOC_t *dci_alloc, - NR_SEARCHSPACE_TYPE_t searchSpacetype, - int16_t eNB_id, - uint8_t nr_tti_rx, - uint8_t dci_fields_sizes_cnt[MAX_NR_DCI_DECODED_SLOT][NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - crc_scrambled_t *crc_scrambled, - format_found_t *format_found, - uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]); - -int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue, - uint8_t eNB_id, - int frame, - uint8_t nr_tti_rx, - uint64_t dci_pdu[2], - uint16_t rnti, - uint8_t dci_length, - NR_DCI_format_t dci_format, - NR_UE_PDCCH *pdcch_vars, - NR_UE_PDSCH *pdsch_vars, - NR_UE_DLSCH_t **dlsch, - NR_UE_ULSCH_t *ulsch, - NR_DL_FRAME_PARMS *frame_parms, - PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - uint8_t beamforming_mode, - uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES], - NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted); - int nr_rx_pdsch(PHY_VARS_NR_UE *ue, PDSCH_t type, unsigned char eNB_id, @@ -1789,20 +1754,5 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint8_t is_crnti, uint8_t llr8_flag); -int nr_extract_dci_info(PHY_VARS_NR_UE *ue, - uint8_t eNB_id, - lte_frame_type_t frame_type, - uint8_t dci_length, - uint16_t rnti, - uint64_t dci_pdu[2], - fapi_nr_dci_pdu_rel15_t *nr_pdci_info_extracted, - uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - NR_DCI_format_t dci_format, - uint8_t nr_tti_rx, - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]); - - /**@}*/ #endif diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index 11521563e4..d49f5c8d00 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -32,7 +32,7 @@ #include "PHY/defs_gNB.h" -void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch); +void free_gNB_ulsch(NR_gNB_ULSCH_t **ulsch,uint8_t N_RB_UL); NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag); @@ -75,7 +75,8 @@ void nr_ulsch_unscrambling(int16_t* llr, void nr_ulsch_procedures(PHY_VARS_gNB *gNB, - gNB_L1_rxtx_proc_t *proc, + int frame_rx, + int slot_rx, int UE_id, uint8_t harq_pid); - +int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 6ca2733120..1eba026fd4 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -48,38 +48,55 @@ #include "common/utils/LOG/log.h" #include //#define DEBUG_ULSCH_DECODING +//#define gNB_DEBUG_TRACE #define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384 +//#define PRINT_CRC_CHECK static uint64_t nb_total_decod =0; static uint64_t nb_error_decod =0; //extern double cpuf; -void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) +void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr,uint8_t N_RB_UL) { int i,r; + uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated + NR_gNB_ULSCH_t *ulsch = *ulschptr; if (ulsch) { + if (N_RB_UL != 273) { + a_segments = a_segments*N_RB_UL; + a_segments = a_segments/273; + } + + uint16_t ulsch_bytes = a_segments*1056; // allocated bytes per segment + for (i=0; i harq_processes[i]) { if (ulsch->harq_processes[i]->b) { - free16(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES); + free16(ulsch->harq_processes[i]->b,ulsch_bytes); ulsch->harq_processes[i]->b = NULL; } - for (r=0; r harq_processes[i]->c[r],(8448)*sizeof(uint8_t)); ulsch->harq_processes[i]->c[r] = NULL; } - for (r=0; r harq_processes[i]->d[r]) { free16(ulsch->harq_processes[i]->d[r],(68*384)*sizeof(int16_t)); ulsch->harq_processes[i]->d[r] = NULL; } } - for (r=0; r<(MAX_NUM_NR_ULSCH_SEGMENTS); r++) { + for (r=0; r harq_processes[i]->w[r]) { + free16(ulsch->harq_processes[i]->w[r],(3*(6144+64))*sizeof(int16_t)); + ulsch->harq_processes[i]->w[r] = NULL; + } + } + for (r=0; r harq_processes[i]->p_nrLDPC_procBuf[r]){ nrLDPC_free_mem(ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]); ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL; @@ -90,7 +107,7 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) } } free16(ulsch,sizeof(NR_gNB_ULSCH_t)); - ulsch = NULL; + *ulschptr = NULL; } } @@ -100,17 +117,14 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8 NR_gNB_ULSCH_t *ulsch; uint8_t exit_flag = 0,i,r; - unsigned char bw_scaling =1; + uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated - switch (N_RB_UL) { - case 106: - bw_scaling =2; - break; + if (N_RB_UL != 273) { + a_segments = a_segments*N_RB_UL; + a_segments = a_segments/273; + } - default: - bw_scaling =1; - break; - } + uint16_t ulsch_bytes = a_segments*1056; // allocated bytes per segment ulsch = (NR_gNB_ULSCH_t *)malloc16(sizeof(NR_gNB_ULSCH_t)); @@ -129,15 +143,15 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8 memset(ulsch->harq_processes[i],0,sizeof(NR_UL_gNB_HARQ_t)); - ulsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + ulsch->harq_processes[i]->b = (uint8_t*)malloc16(ulsch_bytes); if (ulsch->harq_processes[i]->b) - memset(ulsch->harq_processes[i]->b,0,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + memset(ulsch->harq_processes[i]->b,0,ulsch_bytes); else exit_flag=3; if (abstraction_flag == 0) { - for (r=0; r harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem(); @@ -154,6 +168,13 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8 memset(ulsch->harq_processes[i]->d[r],0,(68*384)*sizeof(int16_t)); else exit_flag=2; + + ulsch->harq_processes[i]->w[r] = (int16_t*)malloc16((3*(6144+64))*sizeof(int16_t)); + + if (ulsch->harq_processes[i]->w[r]) + memset(ulsch->harq_processes[i]->w[r],0,(3*(6144+64))*sizeof(int16_t)); + else + exit_flag=2; } } } else { @@ -166,8 +187,8 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8 } printf("new_gNB_ulsch with size %zu: exit_flag = %u\n",sizeof(NR_UL_gNB_HARQ_t), exit_flag); - free_gNB_ulsch(ulsch); - + free_gNB_ulsch(&ulsch,N_RB_UL); + return(NULL); } @@ -176,99 +197,103 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) unsigned char i, j; if (ulsch) { - ulsch->harq_mask = 0; - ulsch->bundling = 0; - ulsch->beta_offset_cqi_times8 = 0; - ulsch->beta_offset_ri_times8 = 0; - ulsch->beta_offset_harqack_times8 = 0; - ulsch->Msg3_active = 0; - ulsch->Msg3_flag = 0; - ulsch->Msg3_subframe = 0; - ulsch->Msg3_frame = 0; - ulsch->rnti = 0; - ulsch->rnti_type = 0; - ulsch->cyclicShift = 0; - ulsch->cooperation_flag = 0; - ulsch->Mlimit = 0; - ulsch->max_ldpc_iterations = 0; - ulsch->last_iteration_cnt = 0; - ulsch->num_active_cba_groups = 0; - for (i=0;i cba_rnti[i] = 0; - for (i=0;i harq_process_id[i] = 0; + ulsch->harq_mask = 0; + ulsch->bundling = 0; + ulsch->beta_offset_cqi_times8 = 0; + ulsch->beta_offset_ri_times8 = 0; + ulsch->beta_offset_harqack_times8 = 0; + ulsch->Msg3_active = 0; + ulsch->Msg3_flag = 0; + ulsch->Msg3_subframe = 0; + ulsch->Msg3_frame = 0; + ulsch->rnti = 0; + ulsch->rnti_type = 0; + ulsch->cyclicShift = 0; + ulsch->cooperation_flag = 0; + ulsch->Mlimit = 0; + ulsch->max_ldpc_iterations = 0; + ulsch->last_iteration_cnt = 0; + ulsch->num_active_cba_groups = 0; + for (i=0;i cba_rnti[i] = 0; + for (i=0;i harq_process_id[i] = 0; - for (i=0; i harq_processes[i]){ - /// Nfapi ULSCH PDU - //nfapi_nr_ul_config_ulsch_pdu ulsch_pdu; - ulsch->harq_processes[i]->frame=0; - ulsch->harq_processes[i]->subframe=0; - ulsch->harq_processes[i]->round=0; - ulsch->harq_processes[i]->TPC=0; - ulsch->harq_processes[i]->mimo_mode=0; - ulsch->harq_processes[i]->dci_alloc=0; - ulsch->harq_processes[i]->rar_alloc=0; - ulsch->harq_processes[i]->status=0; - ulsch->harq_processes[i]->subframe_scheduling_flag=0; - ulsch->harq_processes[i]->subframe_cba_scheduling_flag=0; - ulsch->harq_processes[i]->phich_active=0; - ulsch->harq_processes[i]->phich_ACK=0; - ulsch->harq_processes[i]->previous_first_rb=0; - ulsch->harq_processes[i]->handled=0; - ulsch->harq_processes[i]->delta_TF=0; + for (i=0; i harq_processes[i]){ + /// Nfapi ULSCH PDU + //nfapi_nr_ul_config_ulsch_pdu ulsch_pdu; + ulsch->harq_processes[i]->frame=0; + ulsch->harq_processes[i]->subframe=0; + ulsch->harq_processes[i]->round=0; + ulsch->harq_processes[i]->TPC=0; + ulsch->harq_processes[i]->mimo_mode=0; + ulsch->harq_processes[i]->dci_alloc=0; + ulsch->harq_processes[i]->rar_alloc=0; + ulsch->harq_processes[i]->status=0; + ulsch->harq_processes[i]->subframe_scheduling_flag=0; + ulsch->harq_processes[i]->subframe_cba_scheduling_flag=0; + ulsch->harq_processes[i]->phich_active=0; + ulsch->harq_processes[i]->phich_ACK=0; + ulsch->harq_processes[i]->previous_first_rb=0; + ulsch->harq_processes[i]->handled=0; + ulsch->harq_processes[i]->delta_TF=0; - ulsch->harq_processes[i]->TBS=0; - /// Pointer to the payload (38.212 V15.4.0 section 5.1) - //uint8_t *b; - ulsch->harq_processes[i]->B=0; - /// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2) - //uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS]; - ulsch->harq_processes[i]->K=0; - ulsch->harq_processes[i]->F=0; - ulsch->harq_processes[i]->C=0; - /// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2) - //int16_t *d[MAX_NUM_NR_ULSCH_SEGMENTS]; - /// LDPC processing buffer - //t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_ULSCH_SEGMENTS]; - ulsch->harq_processes[i]->Z=0; - /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) - //int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448]; - ulsch->harq_processes[i]->E=0; + ulsch->harq_processes[i]->TBS=0; + /// Pointer to the payload (38.212 V15.4.0 section 5.1) + //uint8_t *b; + ulsch->harq_processes[i]->B=0; + /// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2) + //uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS]; + ulsch->harq_processes[i]->K=0; + ulsch->harq_processes[i]->F=0; + ulsch->harq_processes[i]->C=0; + /// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2) + //int16_t *d[MAX_NUM_NR_ULSCH_SEGMENTS]; + /// LDPC processing buffer + //t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_ULSCH_SEGMENTS]; + ulsch->harq_processes[i]->Z=0; + /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) + //int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448]; + ulsch->harq_processes[i]->E=0; - ulsch->harq_processes[i]->n_DMRS=0; - ulsch->harq_processes[i]->n_DMRS2=0; - ulsch->harq_processes[i]->previous_n_DMRS=0; + ulsch->harq_processes[i]->n_DMRS=0; + ulsch->harq_processes[i]->n_DMRS2=0; + ulsch->harq_processes[i]->previous_n_DMRS=0; - ulsch->harq_processes[i]->cqi_crc_status=0; - for (j=0;j harq_processes[i]->o[j]=0; - ulsch->harq_processes[i]->uci_format=0; - ulsch->harq_processes[i]->Or1=0; - ulsch->harq_processes[i]->Or2=0; - ulsch->harq_processes[i]->o_RI[0]=0; ulsch->harq_processes[i]->o_RI[1]=0; - ulsch->harq_processes[i]->O_RI=0; - ulsch->harq_processes[i]->o_ACK[0]=0; ulsch->harq_processes[i]->o_ACK[1]=0; - ulsch->harq_processes[i]->o_ACK[2]=0; ulsch->harq_processes[i]->o_ACK[3]=0; - ulsch->harq_processes[i]->O_ACK=0; - ulsch->harq_processes[i]->V_UL_DAI=0; - /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27) - //int8_t q[MAX_CQI_PAYLOAD]; - ulsch->harq_processes[i]->o_RCC=0; - /// coded and interleaved CQI bits - //int8_t o_w[(MAX_CQI_BITS+8)*3]; - /// coded CQI bits - //int8_t o_d[96+((MAX_CQI_BITS+8)*3)]; - for (j=0;j harq_processes[i]->q_ACK[j]=0; - for (j=0;j harq_processes[i]->q_RI[j]=0; - /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled - //uint8_t h[MAX_NUM_CHANNEL_BITS]; - /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) - //int16_t w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)]; - } - } + ulsch->harq_processes[i]->cqi_crc_status=0; + for (j=0;j harq_processes[i]->o[j]=0; + ulsch->harq_processes[i]->uci_format=0; + ulsch->harq_processes[i]->Or1=0; + ulsch->harq_processes[i]->Or2=0; + ulsch->harq_processes[i]->o_RI[0]=0; ulsch->harq_processes[i]->o_RI[1]=0; + ulsch->harq_processes[i]->O_RI=0; + ulsch->harq_processes[i]->o_ACK[0]=0; ulsch->harq_processes[i]->o_ACK[1]=0; + ulsch->harq_processes[i]->o_ACK[2]=0; ulsch->harq_processes[i]->o_ACK[3]=0; + ulsch->harq_processes[i]->O_ACK=0; + ulsch->harq_processes[i]->V_UL_DAI=0; + /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27) + //int8_t q[MAX_CQI_PAYLOAD]; + ulsch->harq_processes[i]->o_RCC=0; + /// coded and interleaved CQI bits + //int8_t o_w[(MAX_CQI_BITS+8)*3]; + /// coded CQI bits + //int8_t o_d[96+((MAX_CQI_BITS+8)*3)]; + for (j=0;j harq_processes[i]->q_ACK[j]=0; + for (j=0;j harq_processes[i]->q_RI[j]=0; + /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled + //uint8_t h[MAX_NUM_CHANNEL_BITS]; + /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + //int16_t w[MAX_NUM_NR_ULSCH_SEGMENTS][3*(6144+64)]; + } + } } } +#ifdef PRINT_CRC_CHECK + static uint32_t prnt_crc_cnt = 0; +#endif + uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint8_t UE_id, short *ulsch_llr, @@ -287,9 +312,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0; uint8_t crc_type; int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))); + +#ifdef PRINT_CRC_CHECK + prnt_crc_cnt++; +#endif - NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id+1][0]; + NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0]; NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid]; nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &harq_process->ulsch_pdu.ulsch_pdu_rel15; @@ -297,11 +326,15 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, t_nrLDPC_dec_params* p_decParams = &decParams; t_nrLDPC_time_stats procTime; t_nrLDPC_time_stats* p_procTime = &procTime ; + if (!harq_process) { + printf("ulsch_decoding.c: NULL harq_process pointer\n"); + return (ulsch->max_ldpc_iterations + 1); + } t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf; int16_t z [68*384]; int8_t l [68*384]; - uint8_t kc; + uint8_t kc=255; uint8_t Ilbrm = 0; uint32_t Tbslbrm = 950984; double Coderate = 0.0; @@ -310,6 +343,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint16_t nb_rb = nfapi_ulsch_pdu_rel15->number_rbs; uint16_t number_symbols = nfapi_ulsch_pdu_rel15->number_symbols; uint8_t Qm = nfapi_ulsch_pdu_rel15->Qm; + uint16_t R = nfapi_ulsch_pdu_rel15->R; uint8_t mcs = nfapi_ulsch_pdu_rel15->mcs; uint8_t n_layers = nfapi_ulsch_pdu_rel15->n_layers; uint8_t nb_re_dmrs = nfapi_ulsch_pdu_rel15->nb_re_dmrs; @@ -324,60 +358,37 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, if (!ulsch_llr) { printf("ulsch_decoding.c: NULL ulsch_llr pointer\n"); - return(ulsch->max_ldpc_iterations); - } - - if (!harq_process) { - printf("ulsch_decoding.c: NULL harq_process pointer\n"); - return(ulsch->max_ldpc_iterations); + return (ulsch->max_ldpc_iterations + 1); } if (!frame_parms) { printf("ulsch_decoding.c: NULL frame_parms pointer\n"); - return(ulsch->max_ldpc_iterations); + return (ulsch->max_ldpc_iterations + 1); } // harq_process->trials[nfapi_ulsch_pdu_rel15->round]++; - - harq_process->TBS = nr_compute_tbs(mcs, nb_rb, number_symbols, nb_re_dmrs, length_dmrs, n_layers); + harq_process->TBS = nr_compute_tbs(Qm, R, nb_rb, number_symbols, nb_re_dmrs*length_dmrs, 0, n_layers); A = harq_process->TBS; - ret = ulsch->max_ldpc_iterations; - - G = nr_get_G(nb_rb, number_symbols, nb_re_dmrs, length_dmrs, Qm, n_layers); - // G = 0; - // G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers); + ret = ulsch->max_ldpc_iterations + 1; - LOG_I(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, mcs, n_layers, nb_symb_sch,nb_rb); + G = nr_get_G(nb_rb, number_symbols, nb_re_dmrs, length_dmrs, Qm, n_layers); + + LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, mcs, n_layers, nb_symb_sch,nb_rb); if (harq_process->round == 0) { // This is a new packet, so compute quantities regarding segmentation harq_process->B = A+24; - // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F) - nr_segmentation(NULL, - NULL, - harq_process->B, - &harq_process->C, - &harq_process->K, - &harq_process->Z, // [hna] Z is Zc - &harq_process->F); + if (R<1024) + Coderate = (float) R /(float) 1024; + else + Coderate = (float) R /(float) 2048; - p_decParams->Z = harq_process->Z; - -#ifdef DEBUG_ULSCH_DECODING - printf("ulsch decoding nr segmentation Z %d\n", p_decParams->Z); - if (!frame%100) - printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl); -#endif - } - - Coderate = (float) A /(float) G; - - if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ - p_decParams->BG = 2; - if (Coderate < 0.3333) { + if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ + p_decParams->BG = 2; + if (Coderate < 0.3333) { p_decParams->R = 15; kc = 52; } @@ -405,8 +416,23 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, } } - //printf("coderate %f kc %d \n", Coderate, kc); + // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F) + nr_segmentation(NULL, + NULL, + harq_process->B, + &harq_process->C, + &harq_process->K, + &harq_process->Z, // [hna] Z is Zc + &harq_process->F, + p_decParams->BG); +#ifdef DEBUG_ULSCH_DECODING + printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z); + if (!frame%100) + printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, harq_process->Z, harq_process->Nl); +#endif + } + p_decParams->Z = harq_process->Z; p_decParams->numMaxIter = ulsch->max_ldpc_iterations; @@ -415,36 +441,28 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, err_flag = 0; r_offset = 0; - unsigned char bw_scaling =1; + uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated - switch (frame_parms->N_RB_UL) { + if (nb_rb != 273) { + a_segments = a_segments*nb_rb; + a_segments = a_segments/273; + } - case 106: - bw_scaling =2; - break; - - default: - bw_scaling =1; - break; - } - - if (harq_process->C > MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling) { - LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling); - return((1+ulsch->max_ldpc_iterations)); + if (harq_process->C > a_segments) { + LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments); + return (ulsch->max_ldpc_iterations + 1); } #ifdef DEBUG_ULSCH_DECODING printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); #endif - opp_enabled=1; + //opp_enabled=1; - Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb" + Kr = harq_process->K; Kr_bytes = Kr>>3; K_bytes_F = Kr_bytes-(harq_process->F>>3); - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, nfapi_ulsch_pdu_rel15->n_layers); - for (r=0; r C; r++) { E = nr_get_E(G, harq_process->C, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers, r); @@ -494,6 +512,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ///////////////////////// harq_process->e =====> harq_process->d ///////////////////////// + Tbslbrm = nr_compute_tbslbrm(0,nb_rb,nfapi_ulsch_pdu_rel15->n_layers,harq_process->C); + if (nr_rate_matching_ldpc_rx(Ilbrm, Tbslbrm, p_decParams->BG, @@ -503,12 +523,14 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, harq_process->C, nfapi_ulsch_pdu_rel15->rv, (harq_process->round==0)?1:0, - E)==-1) { + E, + harq_process->F, + Kr-harq_process->F-2*(p_decParams->Z))==-1) { #if gNB_TIMING_TRACE stop_meas(ulsch_rate_unmatching_stats); #endif LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n"); - return(ulsch->max_ldpc_iterations); + return (ulsch->max_ldpc_iterations + 1); } else { #if gNB_TIMING_TRACE stop_meas(ulsch_rate_unmatching_stats); @@ -523,7 +545,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0); } - printf("decoder input(segment %d) :",r); + printf("decoder input(segment %u) :",r); int i; for (i=0;i<(3*8*Kr_bytes)+12;i++) printf("%d : %d\n",i,harq_process->d[r][i]); @@ -560,7 +582,10 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); } - for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) { + AssertFatal(kc!=255,""); + j+=(harq_process->F>>3); + // for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) { + for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) { pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); } @@ -584,19 +609,24 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, p_procTime); if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - LOG_I(PHY, "Segment %d CRC OK\n",r); - ret = 2; + #ifdef PRINT_CRC_CHECK + //if (prnt_crc_cnt % 10 == 0) + LOG_I(PHY, "Segment %d CRC OK\n",r); + #endif + ret = no_iteration_ldpc; } else { - LOG_I(PHY, "CRC NOK\n"); - ret = 1+ulsch->max_ldpc_iterations; + #ifdef PRINT_CRC_CHECK + //if (prnt_crc_cnt%10 == 0) + LOG_I(PHY, "CRC NOK\n"); + #endif + ret = ulsch->max_ldpc_iterations + 1; } - + nb_total_decod++; + if (no_iteration_ldpc > ulsch->max_ldpc_iterations){ nb_error_decod++; } - - ret=no_iteration_ldpc; for (int m=0; m < Kr>>3; m ++) { harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; @@ -606,7 +636,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, //printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]); for (int k=0;k>3;k++) printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); - printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret); + printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret); //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4); #endif @@ -615,7 +645,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, #endif } - if ((err_flag == 0) && (ret>=(1+ulsch->max_ldpc_iterations))) { + if ((err_flag == 0) && (ret >= (ulsch->max_ldpc_iterations + 1))) { // a Code segment is in error so break; LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1); err_flag = 1; @@ -633,16 +663,16 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, if (err_flag == 1) { -#if gNB_DEBUG_TRACE - LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", - phy_vars_gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); +#ifdef gNB_DEBUG_TRACE + LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d) Kr %d r %d\n", + phy_vars_gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,Kr,r); #endif // harq_process->harq_ack.ack = 0; // harq_process->harq_ack.harq_id = harq_pid; // harq_process->harq_ack.send_harq_status = 1; // harq_process->errors[harq_process->round]++; - harq_process->round++; + //harq_process->round++; if (harq_process->round >= ulsch->Mlimit) { harq_process->status = SCH_IDLE; @@ -657,13 +687,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, } harq_process->handled = 1; - return((1+ulsch->max_ldpc_iterations)); + return (ulsch->max_ldpc_iterations + 1); } else { -#if gNB_DEBUG_TRACE - LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", - phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); +#ifdef gNB_DEBUG_TRACE + LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n", + phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS); #endif harq_process->status = SCH_IDLE; @@ -694,7 +724,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); #ifdef DEBUG_ULSCH_DECODING - printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); + printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes); printf("copied %d bytes to b sequence (harq_pid %d)\n", (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); printf("b[0] = %x,c[%d] = %x\n", diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index d70e61e358..b961b592d5 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -3,8 +3,13 @@ #include "nr_transport_proto.h" #include "PHY/impl_defs_top.h" #include "PHY/NR_TRANSPORT/nr_sch_dmrs.h" +#include "PHY/NR_ESTIMATION/nr_ul_estimation.h" #include "PHY/defs_nr_common.h" +//#define DEBUG_CH_COMP +//#define DEBUG_RB_EXT +//#define DEBUG_CH_MAG + void nr_idft(uint32_t *z, uint32_t Msc_PUSCH) { @@ -216,7 +221,9 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH) } void nr_ulsch_extract_rbs_single(int **rxdataF, + int **ul_ch_estimates, int **rxdataF_ext, + int **ul_ch_estimates_ext, uint32_t rxdataF_ext_offset, // unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment unsigned char symbol, @@ -227,12 +234,22 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, unsigned short start_re, re, nb_re_pusch; unsigned char aarx, is_dmrs_symbol = 0; uint32_t rxF_ext_index = 0; + uint32_t ul_ch0_ext_index = 0; + uint32_t ul_ch0_index = 0; int16_t *rxF,*rxF_ext; + int *ul_ch0,*ul_ch0_ext; + +#ifdef DEBUG_RB_EXT + + printf("--------------------symbol = %d-----------------------\n", symbol); + printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * nb_rb_pusch); + +#endif is_dmrs_symbol = (symbol == 2) ? 1 : 0; //to be updated from config - start_re = frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB); + start_re = (frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size; nb_re_pusch = NR_NB_SC_PER_RB * nb_rb_pusch; @@ -241,19 +258,710 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, rxF = (int16_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; rxF_ext = (int16_t *)&rxdataF_ext[aarx][symbol * nb_re_pusch]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6 + ul_ch0 = &ul_ch_estimates[aarx][(2*(frame_parms->ofdm_symbol_size))]; // DMRS REs are only in symbol 2 (to be updated from config) + ul_ch0_ext = &ul_ch_estimates_ext[aarx][symbol*nb_re_pusch]; + for (re = 0; re < nb_re_pusch; re++) { if ( (is_dmrs_symbol && ((re&1) != 0)) || (is_dmrs_symbol == 0) ) { // [hna] (re&1) != frame_parms->nushift) assuming only dmrs type 1 and mapping type A // frame_parms->nushift should be initialized with 0 rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]); + ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index]; + + #ifdef DEBUG_RB_EXT + printf("rxF_ext[%d] = %d\n", rxF_ext_index, rxF_ext[rxF_ext_index]); + printf("rxF_ext[%d] = %d\n", rxF_ext_index+1, rxF_ext[rxF_ext_index+1]); + printf("ul_ch0_ext[%d] = %d\n", 2*ul_ch0_ext_index, ((int16_t *)ul_ch0_ext)[2*ul_ch0_ext_index]); + printf("ul_ch0_ext[%d] = %d\n", 2*ul_ch0_ext_index + 1, ((int16_t *)ul_ch0_ext)[2*ul_ch0_ext_index + 1]); + #endif + rxF_ext_index = rxF_ext_index + 2; + ul_ch0_ext_index++; } + ul_ch0_index++; } } } +void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, + NR_DL_FRAME_PARMS *frame_parms, + NR_gNB_ULSCH_t **ulsch_gNB, + uint8_t symbol, + uint8_t pilots, + unsigned short nb_rb) +{ +#if defined(__x86_64__)||defined(__i386__) + + short rb, ch_amp; + unsigned char aatx,aarx; + __m128i *ul_ch128, ch_amp128; + + // Determine scaling amplitude based the symbol + + ch_amp = 1024*8; //((pilots) ? (ulsch_gNB[0]->sqrt_rho_b) : (ulsch_gNB[0]->sqrt_rho_a)); + + LOG_D(PHY,"Scaling PUSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n", symbol, ch_amp, pilots, nb_rb, frame_parms->Ncp, symbol); + // printf("Scaling PUSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); + + ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13 + + for (aatx=0; aatx < frame_parms->nb_antenna_ports_eNB; aatx++) { + for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) { + + ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*nb_rb*NR_NB_SC_PER_RB]; + + if (pilots==1){ + nb_rb = nb_rb>>1; + } + + + for (rb=0;rb >x; + + for (aatx = 0; aatx < frame_parms->nb_antennas_tx; aatx++) + for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { + //clear average level + avg128U = _mm_setzero_si128(); + + ul_ch128=(__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; + + for (rb = 0; rb < nb_rb; rb++) { + avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x)); + avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[1], ul_ch128[1]), x)); + avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[2], ul_ch128[2]), x)); + ul_ch128+=3; + } + + avg[(aatx<<1)+aarx] = (((int32_t*)&avg128U)[0] + + ((int32_t*)&avg128U)[1] + + ((int32_t*)&avg128U)[2] + + ((int32_t*)&avg128U)[3] ) / y; + + } + + _mm_empty(); + _m_empty(); + +#elif defined(__arm__) + + short rb; + unsigned char aatx, aarx, nre = 12, symbol_mod; + int32x4_t avg128U; + int16x4_t *ul_ch128; + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + for (aatx=0; aatx nb_antenna_ports_eNB; aatx++) + for (aarx=0; aarx nb_antennas_rx; aarx++) { + //clear average level + avg128U = vdupq_n_s32(0); + // 5 is always a symbol with no pilots for both normal and extended prefix + + ul_ch128 = (int16x4_t *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12]; + + for (rb = 0; rb < nb_rb; rb++) { + // printf("rb %d : ",rb); + // print_shorts("ch",&ul_ch128[0]); + avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[0], ul_ch128[0])); + avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[1], ul_ch128[1])); + avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[2], ul_ch128[2])); + avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[3], ul_ch128[3])); + + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) { + ul_ch128+=4; + } else { + avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[4], ul_ch128[4])); + avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[5], ul_ch128[5])); + ul_ch128+=6; + } + + /* + if (rb==0) { + print_shorts("ul_ch128",&ul_ch128[0]); + print_shorts("ul_ch128",&ul_ch128[1]); + print_shorts("ul_ch128",&ul_ch128[2]); + } + */ + } + + if (symbol==2) //assume start symbol 2 + nre=6; + else + nre=12; + + avg[(aatx<<1)+aarx] = (((int32_t*)&avg128U)[0] + + ((int32_t*)&avg128U)[1] + + ((int32_t*)&avg128U)[2] + + ((int32_t*)&avg128U)[3] ) / (nb_rb*nre); + } + + +#endif +} + +void nr_ulsch_channel_compensation(int **rxdataF_ext, + int **ul_ch_estimates_ext, + int **ul_ch_mag, + int **ul_ch_magb, + int **rxdataF_comp, + int **rho, + NR_DL_FRAME_PARMS *frame_parms, + unsigned char symbol, + uint8_t pilots, + unsigned char mod_order, + unsigned short nb_rb, + unsigned char output_shift) +{ + +#ifdef DEBUG_CH_COMP + int16_t *rxF, *ul_ch; + int prnt_idx; + + + rxF = (int16_t *)&rxdataF_ext[0][(symbol*nb_rb*12)]; + ul_ch = (int16_t *)&ul_ch_estimates_ext[0][symbol*nb_rb*12]; + + printf("--------------------symbol = %d, mod_order = %d, output_shift = %d-----------------------\n", symbol, mod_order, output_shift); + printf("----------------Before compansation------------------\n"); + + for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx++){ + + printf("rxF[%d] = %d\n", prnt_idx, rxF[prnt_idx]); + printf("ul_ch[%d] = %d\n", prnt_idx, ul_ch[prnt_idx]); + + } + +#endif + +#ifdef DEBUG_CH_MAG + int16_t *ch_mag; + int print_idx; + + + ch_mag = (int16_t *)&ul_ch_mag[0][(symbol*nb_rb*12)]; + + printf("--------------------symbol = %d, mod_order = %d-----------------------\n", symbol, mod_order); + printf("----------------Before computation------------------\n"); + + for (print_idx=0;print_idx<50;print_idx++){ + + printf("ch_mag[%d] = %d\n", print_idx, ch_mag[print_idx]); + + } + +#endif + +#if defined(__i386) || defined(__x86_64) + + unsigned short rb; + unsigned char aatx,aarx; + __m128i *ul_ch128,*ul_ch128_2,*ul_ch_mag128,*ul_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128; + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b; + QAM_amp128b = _mm_setzero_si128(); + + for (aatx=0; aatx nb_antennas_tx; aatx++) { + + if (mod_order == 4) { + QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) + QAM_amp128b = _mm_setzero_si128(); + } else if (mod_order == 6) { + QAM_amp128 = _mm_set1_epi16(QAM64_n1); // + QAM_amp128b = _mm_set1_epi16(QAM64_n2); + } + + // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); + + for (aarx=0; aarx nb_antennas_rx; aarx++) { + + ul_ch128 = (__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; + ul_ch_mag128 = (__m128i *)&ul_ch_mag[(aatx<<1)+aarx][symbol*nb_rb*12]; + ul_ch_mag128b = (__m128i *)&ul_ch_magb[(aatx<<1)+aarx][symbol*nb_rb*12]; + rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*nb_rb*12]; + rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*nb_rb*12]; + + + for (rb=0; rb 2) { + // get channel amplitude if not QPSK + + //print_shorts("ch:",(int16_t*)&ul_ch128[0]); + + mmtmpD0 = _mm_madd_epi16(ul_ch128[0],ul_ch128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + + mmtmpD1 = _mm_madd_epi16(ul_ch128[1],ul_ch128[1]); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + + // store channel magnitude here in a new field of ulsch + + ul_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + ul_ch_mag128b[0] = ul_ch_mag128[0]; + ul_ch_mag128[0] = _mm_mulhi_epi16(ul_ch_mag128[0],QAM_amp128); + ul_ch_mag128[0] = _mm_slli_epi16(ul_ch_mag128[0],1); + + // print_ints("ch: = ",(int32_t*)&mmtmpD0); + // print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); + // print_shorts("mag:",(int16_t*)&ul_ch_mag128[0]); + + ul_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + ul_ch_mag128b[1] = ul_ch_mag128[1]; + ul_ch_mag128[1] = _mm_mulhi_epi16(ul_ch_mag128[1],QAM_amp128); + ul_ch_mag128[1] = _mm_slli_epi16(ul_ch_mag128[1],1); + + if (pilots==0) { + mmtmpD0 = _mm_madd_epi16(ul_ch128[2],ul_ch128[2]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); + + ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); + ul_ch_mag128b[2] = ul_ch_mag128[2]; + + ul_ch_mag128[2] = _mm_mulhi_epi16(ul_ch_mag128[2],QAM_amp128); + ul_ch_mag128[2] = _mm_slli_epi16(ul_ch_mag128[2],1); + } + + ul_ch_mag128b[0] = _mm_mulhi_epi16(ul_ch_mag128b[0],QAM_amp128b); + ul_ch_mag128b[0] = _mm_slli_epi16(ul_ch_mag128b[0],1); + + + ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128b); + ul_ch_mag128b[1] = _mm_slli_epi16(ul_ch_mag128b[1],1); + + if (pilots==0) { + ul_ch_mag128b[2] = _mm_mulhi_epi16(ul_ch_mag128b[2],QAM_amp128b); + ul_ch_mag128b[2] = _mm_slli_epi16(ul_ch_mag128b[2],1); + } + } + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(ul_ch128[0],rxdataF128[0]); + // print_ints("re",&mmtmpD0); + + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + // print_ints("im",&mmtmpD1); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + // print_ints("re(shift)",&mmtmpD0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + // print_ints("im(shift)",&mmtmpD1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); + rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",ul_ch128); + // print_shorts("pack:",rxdataF_comp128); + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(ul_ch128[1],rxdataF128[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",ul_ch128+1); + // print_shorts("pack:",rxdataF_comp128+1); + + if (pilots==0) { + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(ul_ch128[2],rxdataF128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",ul_ch128+2); + // print_shorts("pack:",rxdataF_comp128+2); + + ul_ch128+=3; + ul_ch_mag128+=3; + ul_ch_mag128b+=3; + rxdataF128+=3; + rxdataF_comp128+=3; + } else { // we have a smaller PUSCH in symbols with pilots so skip last group of 4 REs and increment less + ul_ch128+=2; + ul_ch_mag128+=2; + ul_ch_mag128b+=2; + rxdataF128+=2; + rxdataF_comp128+=2; + } + + } + } + } + + if (rho) { + + + for (aarx=0; aarx nb_antennas_rx; aarx++) { + rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_UL*12]; + ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_UL*12]; + ul_ch128_2 = (__m128i *)&ul_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_UL*12]; + + for (rb=0; rb =(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { + if (frame_parms->nb_antenna_ports_eNB==1) { // 10 out of 12 so don't reduce size + nb_rb=1+(5*nb_rb/6); + } + else { + pilots=1; + } + } + + for (aatx=0; aatx nb_antenna_ports_eNB; aatx++) { + if (mod_order == 4) { + QAM_amp128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10) + QAM_amp128b = vmovq_n_s16(0); + } else if (mod_order == 6) { + QAM_amp128 = vmovq_n_s16(QAM64_n1); // + QAM_amp128b = vmovq_n_s16(QAM64_n2); + } + // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); + + for (aarx=0; aarx nb_antennas_rx; aarx++) { + ul_ch128 = (int16x4_t*)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12]; + ul_ch_mag128 = (int16x8_t*)&ul_ch_mag[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12]; + ul_ch_mag128b = (int16x8_t*)&ul_ch_magb[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12]; + rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_UL*12]; + rxdataF_comp128 = (int16x4x2_t*)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12]; + + for (rb=0; rb 2) { + // get channel amplitude if not QPSK + mmtmpD0 = vmull_s16(ul_ch128[0], ul_ch128[0]); + // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3]; + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits + mmtmpD1 = vmull_s16(ul_ch128[1], ul_ch128[1]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits + mmtmpD0 = vmull_s16(ul_ch128[2], ul_ch128[2]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(ul_ch128[3], ul_ch128[3]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + if (pilots==0) { + mmtmpD0 = vmull_s16(ul_ch128[4], ul_ch128[4]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(ul_ch128[5], ul_ch128[5]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + } + + ul_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b); + ul_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b); + ul_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128); + ul_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128); + + if (pilots==0) { + ul_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b); + ul_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128); + } + } + + mmtmpD0 = vmull_s16(ul_ch128[0], rxdataF128[0]); + //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])] + mmtmpD1 = vmull_s16(ul_ch128[1], rxdataF128[1]); + //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])] + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] + + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[0],*(int16x4_t*)conj)), rxdataF128[0]); + //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])] + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[1],*(int16x4_t*)conj)), rxdataF128[1]); + //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] + + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp128[0] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + mmtmpD0 = vmull_s16(ul_ch128[2], rxdataF128[2]); + mmtmpD1 = vmull_s16(ul_ch128[3], rxdataF128[3]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[2],*(int16x4_t*)conj)), rxdataF128[2]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[3],*(int16x4_t*)conj)), rxdataF128[3]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + + if (pilots==0) { + mmtmpD0 = vmull_s16(ul_ch128[4], rxdataF128[4]); + mmtmpD1 = vmull_s16(ul_ch128[5], rxdataF128[5]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + + + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + + + ul_ch128+=6; + ul_ch_mag128+=3; + ul_ch_mag128b+=3; + rxdataF128+=6; + rxdataF_comp128+=3; + + } else { // we have a smaller PUSCH in symbols with pilots so skip last group of 4 REs and increment less + ul_ch128+=4; + ul_ch_mag128+=2; + ul_ch_mag128b+=2; + rxdataF128+=4; + rxdataF_comp128+=2; + } + } + } + } + + if (rho) { + for (aarx=0; aarx nb_antennas_rx; aarx++) { + rho128 = (int16x4x2_t*)&rho[aarx][symbol*frame_parms->N_RB_UL*12]; + ul_ch128 = (int16x4_t*)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_UL*12]; + ul_ch128_2 = (int16x4_t*)&ul_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_UL*12]; + for (rb=0; rb frame_parms; - nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15; - uint32_t nb_re_pusch; - - if(symbol == rel15_ul->start_symbol) - gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0; + nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15; + uint32_t nb_re_pusch, bwp_start_subcarrier; + int avgs; + int avg[4]; - if (symbol == 2) // [hna] here it is assumed that symbol 2 carries 6 DMRS REs (dmrs-type 1) + pilots = 0; + first_symbol_flag = 0; + + if(symbol == rel15_ul->start_symbol){ + gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0; + first_symbol_flag = 1; + } + + if (symbol == rel15_ul->start_symbol){ // [hna] here it is assumed that first carries 6 DMRS REs (dmrs-type 1) nb_re_pusch = rel15_ul->number_rbs * 6; - else + pilots = 1; + } else { nb_re_pusch = rel15_ul->number_rbs * NR_NB_SC_PER_RB; + pilots = 0; + } + + bwp_start_subcarrier = (rel15_ul->start_rb*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; + + //---------------------------------------------------------- + //--------------------- Channel estimation --------------------- + //---------------------------------------------------------- + + if (pilots == 1) + nr_pusch_channel_estimation(gNB, + 0, + nr_tti_rx, + 0, // p + symbol, + bwp_start_subcarrier, + rel15_ul->number_rbs); //---------------------------------------------------------- //--------------------- RBs extraction --------------------- //---------------------------------------------------------- nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF, + gNB->pusch_vars[UE_id]->ul_ch_estimates, gNB->pusch_vars[UE_id]->rxdataF_ext, + gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, gNB->pusch_vars[UE_id]->rxdataF_ext_offset, // rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment symbol, @@ -288,6 +1024,44 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, rel15_ul->number_rbs, frame_parms); + nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, + frame_parms, + gNB->ulsch[UE_id], + symbol, + pilots, + rel15_ul->number_rbs); + + if (first_symbol_flag==1) { + + nr_ulsch_channel_level(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, + frame_parms, + avg, + symbol, + nb_re_pusch, + rel15_ul->number_rbs); + avgs = 0; + + for (aatx=0;aatx nb_antennas_tx;aatx++) + for (aarx=0;aarx nb_antennas_rx;aarx++) + avgs = cmax(avgs,avg[(aatx<<1)+aarx]); + + gNB->pusch_vars[UE_id]->log2_maxh = (log2_approx(avgs)/2)+1; + + } + + nr_ulsch_channel_compensation(gNB->pusch_vars[UE_id]->rxdataF_ext, + gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, + gNB->pusch_vars[UE_id]->ul_ch_mag0, + gNB->pusch_vars[UE_id]->ul_ch_magb0, + gNB->pusch_vars[UE_id]->rxdataF_comp, + (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[UE_id]->rho : NULL, + frame_parms, + symbol, + pilots, + rel15_ul->Qm, + rel15_ul->number_rbs, + gNB->pusch_vars[UE_id]->log2_maxh); + #ifdef NR_SC_FDMA nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], nb_re_pusch); #endif @@ -296,14 +1070,15 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, //-------------------- LLRs computation -------------------- //---------------------------------------------------------- - nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_ext[0][symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], - gNB->pusch_vars[UE_id]->ul_ch_mag, - gNB->pusch_vars[UE_id]->ul_ch_magb, + nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], + gNB->pusch_vars[UE_id]->ul_ch_mag0, + gNB->pusch_vars[UE_id]->ul_ch_magb0, &gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->Qm], + rel15_ul->number_rbs, nb_re_pusch, symbol, rel15_ul->Qm); - + gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c index d2d8cdd927..233ecd8de7 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c @@ -30,7 +30,6 @@ * \warning */ - #include "PHY/defs_nr_common.h" #include "PHY/sse_intrin.h" #include "PHY/impl_defs_top.h" @@ -71,23 +70,20 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp, void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, int32_t **ul_ch_mag, int16_t *ulsch_llr, + uint32_t nb_rb, uint32_t nb_re, uint8_t symbol) { + #if defined(__x86_64__) || defined(__i386__) __m128i *rxF = (__m128i*)rxdataF_comp; - // __m128i *ch_mag; // [hna] This should be uncommented once channel estimation is implemented + __m128i *ch_mag; __m128i llr128[2]; uint32_t *llr32; - // [hna] temp_channel and one_over_sqrt_2 are for temporary use until channel estimation is implemented - // else ul_ch_mag and ul_ch_magb should be used after channel estimation has benn implemented - __m128i temp_channel; - int16_t one_over_sqrt_2 = 23170; - #elif defined(__arm__) int16x8_t *rxF = (int16x8_t*)&rxdataF_comp; - // int16x8_t *ch_mag; // [hna] This should be uncommented once channel estimation is implemented + int16x8_t *ch_mag; int16x8_t xmm0; int16_t *llr16; #endif @@ -103,21 +99,16 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, llr16 = (int16_t*)ulsch_llr; #endif -// [hna] This should be uncommented once channel estimation is implemented -// ------------------------------------------------------------ -// #if defined(__x86_64__) || defined(__i386__) -// ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)]; -// #elif defined(__arm__) -// ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)]; -// #endif -// ------------------------------------------------------------ +#if defined(__x86_64__) || defined(__i386__) + ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)]; +#elif defined(__arm__) + ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)]; +#endif len_mod4 = nb_re&3; nb_re >>= 2; // length in quad words (4 REs) nb_re += (len_mod4 == 0 ? 0 : 1); - temp_channel = _mm_set1_epi16((QAM16_n1 * one_over_sqrt_2)>>(2*15-AMP_SHIFT)); - for (i=0; i |y_R|, registers of odd index in xmm0-> |y_I| - xmm0 = _mm_subs_epi16(temp_channel,xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2 + xmm0 = _mm_subs_epi16(ch_mag[i],xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2 llr128[0] = _mm_unpacklo_epi32(rxF[i],xmm0); // llr128[0] contains the llrs of the 1st and 2nd REs llr128[1] = _mm_unpackhi_epi32(rxF[i],xmm0); // llr128[1] contains the llrs of the 3rd and 4th REs @@ -186,52 +177,43 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, int32_t **ul_ch_mag, int32_t **ul_ch_magb, int16_t *ulsch_llr, + uint32_t nb_rb, uint32_t nb_re, uint8_t symbol) { + #if defined(__x86_64__) || defined(__i386__) __m128i *rxF = (__m128i*)rxdataF_comp; - // __m128i *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented - - // [hna] temp_channel and one_over_sqrt_2 are for temporary use until channel estimation is implemented - // else ul_ch_mag and ul_ch_magb should be used after channel estimation has been implemented - __m128i temp_channel[2]; - int16_t one_over_sqrt_2 = 23170; - + __m128i *ch_mag,*ch_magb; #elif defined(__arm__) int16x8_t *rxF = (int16x8_t*)&rxdataF_comp; - // int16x8_t *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented + int16x8_t *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented int16x8_t xmm1,xmm2; #endif int i; unsigned char len_mod4; -// [hna] This should be uncommented once channel estimation is implemented -// ------------------------------------------------------------------------- -// #if defined(__x86_64__) || defined(__i386__) -// ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_UL*12)]; -// ch_magb = (__m128i*)&ul_ch_magb[0][(symbol*frame_parms->N_RB_UL*12)]; -// #elif defined(__arm__) -// ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_UL*12)]; -// ch_magb = (int16x8_t*)&ul_ch_magb[0][(symbol*frame_parms->N_RB_UL*12)]; -// #endif -// ------------------------------------------------------------------------- +#if defined(__x86_64__) || defined(__i386__) + ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)]; + ch_magb = (__m128i*)&ul_ch_magb[0][(symbol*nb_rb*12)]; +#elif defined(__arm__) + ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)]; + ch_magb = (int16x8_t*)&ul_ch_magb[0][(symbol*nb_rb*12)]; +#endif len_mod4 = nb_re&3; nb_re = nb_re>>2; // length in quad words (4 REs) nb_re += ((len_mod4 == 0) ? 0 : 1); - - temp_channel[0] = _mm_set1_epi16((QAM64_n1 * one_over_sqrt_2)>>(2*15-AMP_SHIFT)); - temp_channel[1] = _mm_set1_epi16((QAM64_n2 * one_over_sqrt_2)>>(2*15-AMP_SHIFT)); + for (i=0; i nb_antennas_rx; aa++) { - Re = ((int16_t*)ue->pdcch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_time[aa])[(i<<1)]; - Im = ((int16_t*)ue->pdcch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)]; + Re = ((int16_t*)ue->pbch_vars[eNB_id]->dl_ch_estimates_time[aa])[(i<<1)]; + Im = ((int16_t*)ue->pbch_vars[eNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)]; temp += (Re*Re/2) + (Im*Im/2); } @@ -80,7 +80,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, // do not filter to have proactive timing adjustment //max_pos_fil = max_pos; - if(subframe == 1) + if(subframe == 0) { diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 6df9e0c20e..72ab04c492 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -21,7 +21,7 @@ #include - +#include "SCHED_NR_UE/defs.h" #include "nr_estimation.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "filt16a_32.h" @@ -31,11 +31,11 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, - uint8_t eNB_offset, - unsigned char Ns, - unsigned char symbol, - int dmrss, - NR_UE_SSB *current_ssb) + uint8_t eNB_offset, + unsigned char Ns, + unsigned char symbol, + int dmrss, + NR_UE_SSB *current_ssb) { int pilot[200] __attribute__((aligned(16))); unsigned char aarx; @@ -98,8 +98,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -114,8 +113,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; current_ssb->c_re +=ch[0]; @@ -126,8 +124,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt+=3) { @@ -138,8 +135,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) if (dmrss == 1 && pilot_cnt == 12) { pilot_cnt=48; - //re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 144) : (re_offset+144); + re_offset = (re_offset+144) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; } ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -149,12 +145,11 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, current_ssb->c_im +=ch[1]; #ifdef DEBUG_CH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -165,11 +160,10 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, current_ssb->c_im +=ch[1]; #ifdef DEBUG_CH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -180,12 +174,11 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, current_ssb->c_im +=ch[1]; #ifdef DEBUG_CH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; } @@ -207,11 +200,15 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, uint8_t n_hf) { int pilot[200] __attribute__((aligned(16))); - unsigned char aarx; + unsigned char aarx,p; unsigned short k; unsigned int pilot_cnt; int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr; int ch_offset,symbol_offset; + //int slot_pbch; + //fapi_nr_pbch_config_t *pbch_config = &ue->nrUE_config.pbch_config; + // initialized to 5ms in nr_init_ue for scenarios where UE is not configured (otherwise acquired by cell configuration from gNB or LTE) + //uint8_t ssb_periodicity = 10;// ue->ssb_periodicity; //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; @@ -310,8 +307,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; //for (int i= 0; i<8; i++) @@ -329,8 +325,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -345,8 +340,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; dl_ch+=24; @@ -358,8 +352,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) if (dmrss == 1 && pilot_cnt == 12) { pilot_cnt=48; - //re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 144) : (re_offset+144); + re_offset = (re_offset+144) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; dl_ch += 288; } @@ -367,7 +360,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_CH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fl, ch, @@ -378,8 +371,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i)); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -387,15 +379,14 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_CH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fm, ch, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -403,7 +394,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_CH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fr, @@ -411,13 +402,65 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; dl_ch+=24; } + void (*idft)(int16_t *,int16_t *, int); + + switch (ue->frame_parms.ofdm_symbol_size) { + case 128: + idft = idft128; + break; + + case 256: + idft = idft256; + break; + + case 512: + idft = idft512; + break; + + case 1024: + idft = idft1024; + break; + + case 1536: + idft = idft1536; + break; + + case 2048: + idft = idft2048; + break; + + case 3072: + idft = idft3072; + break; + + case 4096: + idft = idft4096; + break; + + default: + printf("unsupported ofdm symbol size \n"); + assert(0); + } + + if( symbol == 3) + { + // do ifft of channel estimate + for (aarx=0; aarx frame_parms.nb_antennas_rx; aarx++) + for (p=0; p frame_parms.nb_antenna_ports_eNB; p++) { + if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx]) + { + LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, ue->current_thread_id[Ns], symbol, ch_offset); + idft((int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx][ch_offset], + (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1); + } + } + } //} @@ -426,14 +469,14 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, } int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, - uint8_t eNB_offset, - unsigned char Ns, - unsigned char symbol, - unsigned short coreset_start_subcarrier, - unsigned short nb_rb_coreset) + uint8_t eNB_offset, + unsigned char Ns, + unsigned char symbol, + unsigned short coreset_start_subcarrier, + unsigned short nb_rb_coreset) { - int pilot[200] __attribute__((aligned(16))); - unsigned char aarx,p; + + unsigned char aarx; unsigned short k; unsigned int pilot_cnt; int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr; @@ -441,12 +484,9 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; - uint8_t nushift; int **dl_ch_estimates =ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates; int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF; - nushift = 1; - ue->frame_parms.nushift = nushift; if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage ch_offset = ue->frame_parms.ofdm_symbol_size ; @@ -467,14 +507,15 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, fr = filt16a_r1; - // generate pilot + // generate pilot + int pilot[nb_rb_coreset * 3] __attribute__((aligned(16))); nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[0],2000,nb_rb_coreset); for (aarx=0; aarx frame_parms.nb_antennas_rx; aarx++) { pil = (int16_t *)&pilot[0]; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)]; dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size)); @@ -545,12 +586,12 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, if (k >= ue->frame_parms.ofdm_symbol_size){ k-=ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];} + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];} ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDCCH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fl, ch, @@ -566,7 +607,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDCCH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fm, ch, @@ -579,7 +620,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDCCH - printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fr, @@ -597,78 +638,24 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, //} } - - void (*idft)(int16_t *,int16_t *, int); - - switch (ue->frame_parms.ofdm_symbol_size) { - case 128: - idft = idft128; - break; - - case 256: - idft = idft256; - break; - - case 512: - idft = idft512; - break; - - case 1024: - idft = idft1024; - break; - - case 1536: - idft = idft1536; - break; - - case 2048: - idft = idft2048; - break; - - case 3072: - idft = idft3072; - break; - - case 4096: - idft = idft4096; - break; - - default: - printf("unsupported ofdm symbol size \n"); - assert(0); - } - - if( (Ns== 1) && (symbol == 0)) - { - // do ifft of channel estimate - for (aarx=0; aarx frame_parms.nb_antennas_rx; aarx++) - for (p=0; p frame_parms.nb_antenna_ports_eNB; p++) { - if (ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates[(p<<1)+aarx]) - { - LOG_I(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns], symbol); - idft((int16_t*) &ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates[(p<<1)+aarx][0], - (int16_t*) ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1); - } - } - } return(0); } int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, - uint8_t eNB_offset, - unsigned char Ns, - unsigned short p, - unsigned char symbol, - unsigned short bwp_start_subcarrier, - unsigned short nb_rb_pdsch) + uint8_t eNB_offset, + unsigned char Ns, + unsigned short p, + unsigned char symbol, + unsigned short bwp_start_subcarrier, + unsigned short nb_rb_pdsch) { - - int pilot[1320] __attribute__((aligned(16))); + int pilot[3280] __attribute__((aligned(16))); unsigned char aarx; unsigned short k; unsigned int pilot_cnt; - int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr,*fml,*fmr,*fmm; + int16_t ch[2],*pil,*rxF,*dl_ch; + int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh; int ch_offset,symbol_offset; //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; @@ -703,6 +690,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, fmm = filt8_mm0; fml = filt8_m0; fmr = filt8_mr0; + fdcl = filt8_dcl0; + fdcr = filt8_dcr0; + fdclh = filt8_dcl0_h; + fdcrh = filt8_dcr0_h; break; case 1: @@ -712,6 +703,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, fmm = filt8_mm1; fml = filt8_ml1; fmr = filt8_m1; + fdcl = filt8_dcl1; + fdcr = filt8_dcr1; + fdclh = filt8_dcl1_h; + fdcrh = filt8_dcr1_h; break; default: @@ -722,11 +717,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, // generate pilot - nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][0], &pilot[0],1000,0,nb_rb_pdsch); + uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12; + int config_type = 0; // needs to be updated from higher layer + nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][0], &pilot[0],1000,0,nb_rb_pdsch+rb_offset); for (aarx=0; aarx frame_parms.nb_antennas_rx; aarx++) { - pil = (int16_t *)&pilot[0]; + pil = (int16_t *)&pilot[rb_offset*((config_type==0) ? 6:4)]; + k = k % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; @@ -756,8 +754,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //for (int i= 0; i<8; i++) //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); @@ -772,8 +769,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //printf("dl_ch addr %p\n",dl_ch); @@ -791,8 +787,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; dl_ch+=8; @@ -804,7 +799,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDSCH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fm, ch, @@ -812,32 +807,30 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDSCH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fmm, ch, dl_ch, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; dl_ch+=8; } // Treat first 2 pilots specially (right edge) - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDSCH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fm, ch, @@ -848,15 +841,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDSCH printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); - printf("pilot %d: rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u: rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fmr, ch, @@ -864,22 +856,84 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; dl_ch+=8; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDSCH - printf("pilot %d: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fr, ch, dl_ch, 8); //} + + // check if PRB crosses DC and improve estimates around DC + if ((bwp_start_subcarrier < ue->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size)) { + dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; + uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); + uint16_t idxPil = idxDC/2; + re_offset = k; + pil = (int16_t *)&pilot[rb_offset*((config_type==0) ? 6:4)]; + pil += (idxPil-2); + dl_ch += (idxDC-4); + dl_ch = memset(dl_ch, 0, sizeof(int16_t)*10); + re_offset = (re_offset+idxDC/2-2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + // for proper allignment of SIMD vectors + if((ue->frame_parms.N_RB_DL&1)==0) { + + multadd_real_vector_complex_scalar(fdcl, + ch, + dl_ch-4, + 8); + + pil += 4; + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + multadd_real_vector_complex_scalar(fdcr, + ch, + dl_ch-4, + 8); + } else { + multadd_real_vector_complex_scalar(fdclh, + ch, + dl_ch, + 8); + + pil += 4; + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + multadd_real_vector_complex_scalar(fdcrh, + ch, + dl_ch, + 8); + } + + } + +#ifdef DEBUG_PDSCH + dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; + for(uint16_t idxP=0; idxP measurements.rsrp[gNB_index])+ // dB_fixed_times10(RSoffset*12*ue_g[Mod_id][CC_id]->frame_parms.N_RB_DL) + (ue->frame_parms.ss_PBCH_BlockPower*10))/10)); - } + diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 7d383a7aef..96d4462724 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -43,11 +43,20 @@ #include "assertions.h" #include "T.h" -#define DEBUG_DCI_DECODING 1 +//#define DEBUG_DCI_DECODING 1 //#define NR_LTE_PDCCH_DCI_SWITCH #define NR_PDCCH_DCI_RUN // activates new nr functions -#define NR_PDCCH_DCI_DEBUG // activates NR_PDCCH_DCI_DEBUG logs +//#define NR_PDCCH_DCI_DEBUG // activates NR_PDCCH_DCI_DEBUG logs +#ifdef NR_PDCCH_DCI_DEBUG +#define LOG_DNL(a, ...) printf("\n\t\t<-NR_PDCCH_DCI_DEBUG (%s)-> " a, __func__, ##__VA_ARGS__ ) +#define LOG_DD(a, ...) printf("\t<-NR_PDCCH_DCI_DEBUG (%s)-> " a, __func__, ##__VA_ARGS__ ) +#define LOG_DDD(a, ...) printf("\t\t<-NR_PDCCH_DCI_DEBUG (%s)-> " a, __func__, ##__VA_ARGS__ ) +#else +#define LOG_DNL(a...) +#define LOG_DD(a...) +#define LOG_DDD(a...) +#endif #define NR_NBR_CORESET_ACT_BWP 3 // The number of CoreSets per BWP is limited to 3 (including initial CORESET: ControlResourceId 0) #define NR_NBR_SEARCHSPACE_ACT_BWP 10 // The number of SearSpaces per BWP is limited to 10 (including initial SEARCHSPACE: SearchSpaceId 0) @@ -131,24 +140,18 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr, if (coreset_interleaved==0) f_bundle_j=bundle_j; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\n\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_demapping_deinterleaving)-> [r=%d,c=%d] bundle_j(%d) interleaved at f_bundle_j(%d)\n",r,c,bundle_j,f_bundle_j); -#endif + LOG_DNL("[r=%d,c=%d] bundle_j(%d) interleaved at f_bundle_j(%d)\n",r,c,bundle_j,f_bundle_j); } f_reg = (f_bundle_j*reg_bundle_size_L)+(reg%reg_bundle_size_L); - //index_z = 9*reg; - index_z = 9*(uint16_t)floor(reg/coreset_time_dur) + (9*coreset_nbr_rb)*(reg%coreset_time_dur); - //index_llr = 9*(((uint16_t)floor(f_reg/reg_bundle_size_L)+(f_reg)%coreset_time_dur))*(coreset_nbr_rb); + index_z = 9*reg; index_llr = 9*((uint16_t)floor(f_reg/coreset_time_dur)+((f_reg%coreset_time_dur)*(coreset_nbr_rb))); for (int i=0; i<9; i++) { z[index_z + i] = llr[index_llr + i]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_demapping_deinterleaving)-> [reg=%d,bundle_j=%d] z[%d]=(%d,%d) <-> \t[f_reg=%d,fbundle_j=%d] llr[%d]=(%d,%d) \n", + LOG_DDD("[reg=%d,bundle_j=%d] z[%d]=(%d,%d) <-> \t[f_reg=%d,fbundle_j=%d] llr[%d]=(%d,%d) \n", reg,bundle_j,(index_z + i),*(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]), f_reg,f_bundle_j,(index_llr + i),*(int16_t *) &llr[index_llr + i], *(1 + (int16_t *) &llr[index_llr + i])); -#endif } if ((reg%reg_bundle_size_L) == 0) r++; @@ -166,13 +169,11 @@ int32_t nr_pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, pdcch_llrp = &pdcch_llr[2 * symbol * coreset_nbr_rb * 9]; if (!pdcch_llrp) { - printf("pdcch_qpsk_llr: llr is null, symbol %d\n", symbol); + LOG_E(PHY,"pdcch_qpsk_llr: llr is null, symbol %d\n", symbol); return (-1); } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_llr)-> llr logs: pdcch qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llrp-pdcch_llr); -#endif + LOG_DDD("llr logs: pdcch qpsk llr for symbol %d (pos %d), llr offset %ld\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llrp-pdcch_llr); //for (i = 0; i < (frame_parms->N_RB_DL * ((symbol == 0) ? 16 : 24)); i++) { for (i = 0; i < (coreset_nbr_rb * ((symbol == 0) ? 18 : 18)); i++) { @@ -183,9 +184,7 @@ int32_t nr_pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, else *pdcch_llrp = (*rxF); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_llr)-> llr logs: rb=%d i=%d *rxF:%d => *pdcch_llrp:%d\n",i/18,i,*rxF,*pdcch_llrp); -#endif + LOG_DDD("llr logs: rb=%d i=%d *rxF:%d => *pdcch_llrp:%d\n",i/18,i,*rxF,*pdcch_llrp); rxF++; pdcch_llrp++; } @@ -206,7 +205,7 @@ int32_t pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, pdcch_llr8 = &pdcch_llr[2*symbol*frame_parms->N_RB_DL*12]; if (!pdcch_llr8) { - printf("pdcch_qpsk_llr: llr is null, symbol %d\n",symbol); + LOG_E(PHY,"pdcch_qpsk_llr: llr is null, symbol %d\n",symbol); return(-1); } @@ -301,9 +300,8 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, int32_t **rxdataF_ext, int32_t **dl_ch_estimates_ext, uint8_t symbol, - uint32_t high_speed_flag, NR_DL_FRAME_PARMS *frame_parms, - uint64_t coreset_freq_dom, + uint8_t *coreset_freq_dom, uint32_t coreset_nbr_rb, uint32_t n_BWP_start) { /* @@ -329,43 +327,23 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, //uint8_t rb_count_bit; uint8_t i, j, aarx, bitcnt_coreset_freq_dom=0; int32_t *dl_ch0, *dl_ch0_ext, *rxF, *rxF_ext; -#ifdef NR_PDCCH_DCI_DEBUG - int nushiftmod3 = frame_parms->nushift % 3; -#endif -#if defined(DEBUG_DCI_DECODING) || defined(NR_PDCCH_DCI_DEBUG) - uint8_t symbol_mod = (symbol >= (7 - frame_parms->Ncp)) ? symbol - (7 - frame_parms->Ncp) : symbol; -#endif - c_rb = n_BWP_start; // c_rb is the common resource block: RB within the BWP #ifdef DEBUG_DCI_DECODING + uint8_t symbol_mod = (symbol >= (7 - frame_parms->Ncp)) ? symbol - (7 - frame_parms->Ncp) : symbol; LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod); #endif for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { - if (high_speed_flag == 1) { - dl_ch0 = &dl_ch_estimates[aarx][(symbol * (frame_parms->ofdm_symbol_size))]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0 = &dl_ch_estimates[aarx = (%d)][ (symbol * (frame_parms->ofdm_symbol_size (%d))) = (%d)]\n", - aarx,frame_parms->ofdm_symbol_size,(symbol * (frame_parms->ofdm_symbol_size))); -#endif - } else { - dl_ch0 = &dl_ch_estimates[aarx][0]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0 = &dl_ch_estimates[aarx = (%d)][0]\n",aarx); -#endif - } + dl_ch0 = &dl_ch_estimates[aarx][0]; + LOG_DDD("dl_ch0 = &dl_ch_estimates[aarx = (%d)][0]\n",aarx); dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS)]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0_ext = &dl_ch_estimates_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 9) = (%d)]\n", + LOG_DDD("dl_ch0_ext = &dl_ch_estimates_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 9) = (%d)]\n", aarx,symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS)); -#endif rxF_ext = &rxdataF_ext[aarx][symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS)]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> rxF_ext = &rxdataF_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 9) = (%d)]\n", + LOG_DDD("rxF_ext = &rxdataF_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 9) = (%d)]\n", aarx,symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS)); - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> (for symbol=%d, aarx=%d), symbol_mod=%d, nushiftmod3=%d \n",symbol,aarx,symbol_mod,nushiftmod3); -#endif + /* * The following for loop handles treatment of PDCCH contained in table rxdataF (in frequency domain) * In NR the PDCCH IQ symbols are contained within RBs in the CORESET defined by higher layers which is located within the BWP @@ -383,55 +361,34 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, * then the IQ symbol is going to be found at the position 0+c_rb-N_RB_DL/2 in rxdataF and * we have to point the pointer at (1+c_rb-N_RB_DL/2) in rxdataF */ -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> n_BWP_start=%d, coreset_nbr_rb=%d\n",n_BWP_start,coreset_nbr_rb); -#endif + LOG_DDD("n_BWP_start=%d, coreset_nbr_rb=%d\n",n_BWP_start,coreset_nbr_rb); + int c_rb_by6; + c_rb = n_BWP_start; + for (int rb=0;rb >3] & (1<<(c_rb_by6&7))) == 0) c_rb+=6; - for (c_rb = n_BWP_start; c_rb < (n_BWP_start + coreset_nbr_rb + (BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN * offset_discontiguous)); c_rb++) { - //c_rb_tmp = 0; - if (((c_rb - n_BWP_start) % BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN)==0) { - bitcnt_coreset_freq_dom ++; - - while ((((coreset_freq_dom & 0x1FFFFFFFFFFF) >> (CORESET_FREQ_DOMAIN_BITMAP_SIZE - bitcnt_coreset_freq_dom)) & 0x1)== 0) { // 46 -> 45 is number of bits in coreset_freq_dom - // next 6 RB are not part of the CORESET within the BWP as bit in coreset_freq_dom is set to 0 - bitcnt_coreset_freq_dom ++; - //c_rb_tmp = c_rb_tmp + 6; - c_rb = c_rb + BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN; - offset_discontiguous ++; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> we entered here as coreset_freq_dom=%lx (bit %d) is 0, coreset_freq_domain is discontiguous\n",coreset_freq_dom, - (46 - bitcnt_coreset_freq_dom)); -#endif - } - } - - //c_rb = c_rb + c_rb_tmp; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> c_rb=%d\n",c_rb); -#endif + LOG_DDD("c_rb=%d\n",c_rb); rxF=NULL; // first we set initial conditions for pointer to rxdataF depending on the situation of the first RB within the CORESET (c_rb = n_BWP_start) if ((c_rb < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) { //if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): even case rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in even case c_rb (%d) is lower than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_DDD("in even case c_rb (%d) is lower than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))); -#endif } if ((c_rb >= (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // number of RBs is even and c_rb is higher than half system bandwidth (we don't skip DC) // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_DDD("in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))); -#endif //rxF = &rxdataF[aarx][(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol //#ifdef NR_PDCCH_DCI_DEBUG - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + // LOG_DDD("in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", // c_rb,aarx,(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))); //#endif } @@ -440,7 +397,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, //if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): odd case rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))]; #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is lower or equal than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_D(PHY,"in odd case c_rb (%d) is lower or equal than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))); #endif } @@ -450,7 +407,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF just after the first IQ symbols of the RB containing DC rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) - 6 + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - frame_parms->N_RB_DL) - 5 + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_D(PHY,"in odd case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - frame_parms->N_RB_DL) - 5 + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(12*(c_rb - (frame_parms->N_RB_DL>>1)) - 6 + (symbol * (frame_parms->ofdm_symbol_size)))); #endif } @@ -460,30 +417,9 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, // we have to treat the RB in two parts: first part from i=0 to 5, the data is at the end of rxdataF (pointing at the end of the table) rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))]; #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is half N_RB_DL + 1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_D(PHY,"in odd case c_rb (%d) is half N_RB_DL + 1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))); #endif - /*if (symbol_mod > 300) { // this if is going to be removed as DM-RS signals are present in all symbols of PDCCH - for (i = 0; i < 6; i++) { - dl_ch0_ext[i] = dl_ch0[i]; - rxF_ext[i] = rxF[i]; - } - rxF = &rxdataF[aarx][(symbol * (frame_parms->ofdm_symbol_size))]; // we point at the 1st part of the rxdataF in symbol - #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(symbol * (frame_parms->ofdm_symbol_size)) = (%d)]\n", - c_rb,aarx,(symbol * (frame_parms->ofdm_symbol_size))); - #endif - for (; i < 12; i++) { - dl_ch0_ext[i] = dl_ch0[i]; - rxF_ext[i] = rxF[(1 + i - 6)]; - } - nb_rb++; - dl_ch0_ext += 12; - rxF_ext += 12; - dl_ch0 += 12; - rxF += 7; - c_rb++; - } else {*/ j = 0; for (i = 0; i < 6; i++) { //treating first part of the RB note that i=5 would correspond to DC. We treat it in NR @@ -497,10 +433,9 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, // then we point at the begining of the symbol part of rxdataF do process second part of RB rxF = &rxdataF[aarx][((symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(symbol * (frame_parms->ofdm_symbol_size)) = (%d)]\n", + LOG_D(PHY,"in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(symbol * (frame_parms->ofdm_symbol_size)) = (%d)]\n", c_rb,aarx,(symbol * (frame_parms->ofdm_symbol_size))); #endif - for (; i < 12; i++) { if ((i != 9)) { dl_ch0_ext[j] = dl_ch0[i]; @@ -518,34 +453,24 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, //n_BWP_start++; // We have to increment this variable here to be consequent in the for loop afterwards //} } else { // treatment of any RB that does not contain the DC - /*if (symbol_mod > 300) { - memcpy(dl_ch0_ext, dl_ch0, 12 * sizeof(int32_t)); - for (i = 0; i < 12; i++) { - rxF_ext[i] = rxF[i]; - } - nb_rb++; - dl_ch0_ext += 12; - rxF_ext += 12; - dl_ch0 += 12; - //rxF += 12; - } else {*/ j = 0; for (i = 0; i < 12; i++) { if ((i != 1) && (i != 5) && (i != 9)) { rxF_ext[j] = rxF[i]; #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d)\n", + LOG_D(PHY,"RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d)\n", c_rb, i, j, *(short *) &rxF_ext[j],*(1 + (short *) &rxF_ext[j]), i, *(short *) &rxF[i], *(1 + (short *) &rxF[i])); #endif dl_ch0_ext[j] = dl_ch0[i]; - //printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> ch %d => dl_ch0(%d,%d)\n", i, *(short *) &dl_ch0[i], *(1 + (short*) &dl_ch0[i])); + + //LOG_DDD("ch %d => dl_ch0(%d,%d)\n", i, *(short *) &dl_ch0[i], *(1 + (short*) &dl_ch0[i])); //printf("\t-> dl_ch0[%d] => dl_ch0_ext[%d](%d,%d)\n", i,j, *(short *) &dl_ch0[i], *(1 + (short*) &dl_ch0[i])); j++; } else { #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d) \t\t <==> DM-RS PDCCH, this is a pilot symbol\n", + LOG_D(PHY,"RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d) \t\t <==> DM-RS PDCCH, this is a pilot symbol\n", c_rb, i, j, *(short *) &rxF_ext[j], *(1 + (short *) &rxF_ext[j]), i, *(short *) &rxF[i], *(1 + (short *) &rxF[i])); #endif @@ -657,15 +582,13 @@ void nr_pdcch_channel_compensation(int32_t **rxdataF_ext, //print_shorts("rx:",rxdataF128+2); //print_shorts("ch:",dl_ch128+2); //print_shorts("pack:",rxdataF_comp128+2); -#ifdef NR_PDCCH_DCI_DEBUG for (int i=0; i<12 ; i++) - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF128[%d]=(%d,%d) X dlch[%d]=(%d,%d) rxdataF_comp128[%d]=(%d,%d)\n", + LOG_DDD("rxdataF128[%d]=(%d,%d) X dlch[%d]=(%d,%d) rxdataF_comp128[%d]=(%d,%d)\n", (rb*12)+i, ((short *)rxdataF128)[i<<1],((short *)rxdataF128)[1+(i<<1)], (rb*12)+i, ((short *)dl_ch128)[i<<1],((short *)dl_ch128)[1+(i<<1)], (rb*12)+i, ((short *)rxdataF_comp128)[i<<1],((short *)rxdataF_comp128)[1+(i<<1)]); -#endif dl_ch128+=3; rxdataF128+=3; rxdataF_comp128+=3; @@ -738,6 +661,116 @@ void pdcch_siso(NR_DL_FRAME_PARMS *frame_parms, #ifdef NR_PDCCH_DCI_RUN +int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, + uint32_t frame, + uint32_t slot) { + + NR_UE_COMMON *common_vars = &ue->common_vars; + NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[slot]][0]; + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15; + + uint8_t log2_maxh, aarx; + int32_t avgs; + int32_t avgP[4]; + for (int i=0;i nb_search_space;i++) { + + rel15 = &pdcch_vars->pdcch_config[i]; + int n_rb,rb_offset; + get_coreset_rballoc(rel15->coreset.frequency_domain_resource,&n_rb,&rb_offset); + for (int s=rel15->coreset.StartSymbolIndex; + s<(rel15->coreset.StartSymbolIndex+rel15->coreset.duration); + s++) { + + nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[slot]].rxdataF, + pdcch_vars->dl_ch_estimates, + pdcch_vars->rxdataF_ext, + pdcch_vars->dl_ch_estimates_ext, + s, + frame_parms, + rel15->coreset.frequency_domain_resource, + n_rb, + rel15->BWPStart); + + LOG_DD("we enter pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",*avgP); + LOG_DD("in pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n"); + // compute channel level based on ofdm symbol 0 + pdcch_channel_level(pdcch_vars->dl_ch_estimates_ext, + frame_parms, + avgP, + n_rb); + avgs = 0; + + for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) + avgs = cmax(avgs, avgP[aarx]); + + log2_maxh = (log2_approx(avgs) / 2) + 5; //+frame_parms->nb_antennas_rx; +#ifdef UE_DEBUG_TRACE + LOG_D(PHY,"slot %d: pdcch log2_maxh = %d (%d,%d)\n",slot,log2_maxh,avgP[0],avgs); +#endif +#if T_TRACER + T(T_UE_PHY_PDCCH_ENERGY, T_INT(0), T_INT(0), T_INT(frame%1024), T_INT(slot), + T_INT(avgP[0]), T_INT(avgP[1]), T_INT(avgP[2]), T_INT(avgP[3])); +#endif + LOG_DD("we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh); + LOG_DD("in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n"); + // compute LLRs for ofdm symbol 0 only + nr_pdcch_channel_compensation(pdcch_vars->rxdataF_ext, + pdcch_vars->dl_ch_estimates_ext, + pdcch_vars->rxdataF_comp, + NULL, + frame_parms, + s, + log2_maxh, + n_rb); // log2_maxh+I0_shift + if (frame_parms->nb_antennas_rx > 1) { + LOG_DD("we enter pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", + frame_parms->nb_antennas_rx); + pdcch_detection_mrc(frame_parms, pdcch_vars->rxdataF_comp,s); + } + + LOG_DD("we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s); + LOG_DD("in nr_pdcch_llr(rxdataF_comp -> llr)\n"); + nr_pdcch_llr(frame_parms, + pdcch_vars->rxdataF_comp, + pdcch_vars->llr, + s, + n_rb); +#if T_TRACER + + // T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL), + // T_INT(n_pdcch_symbols), + // T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4)); + +#endif +#ifdef DEBUG_DCI_DECODING + printf("demapping: slot %d, mi %d\n",slot,get_mi(frame_parms,slot)); +#endif + } + + LOG_DD("we enter nr_pdcch_demapping_deinterleaving()\n"); + nr_pdcch_demapping_deinterleaving((uint32_t *) pdcch_vars->llr, + (uint32_t *) pdcch_vars->e_rx, + frame_parms, + rel15->coreset.duration, + n_rb, + rel15->coreset.RegBundleSize, + rel15->coreset.InterleaverSize, + rel15->coreset.ShiftIndex); + nr_pdcch_unscrambling(rel15->rnti, + frame_parms, + slot, + pdcch_vars->e_rx, + rel15->coreset.duration*n_rb*9*2, + // get_nCCE(n_pdcch_symbols, frame_parms, mi) * 72, + rel15->coreset.pdcch_dmrs_scrambling_id); + LOG_DD("we end nr_pdcch_unscrambling()\n"); + LOG_DD("Ending nr_rx_pdcch() function\n"); + return (0); + } + +} + /* int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, uint32_t frame, uint8_t nr_tti_rx, @@ -780,7 +813,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, // For each BWP the number of CORESETs is limited to 3 (including initial CORESET Id=0 -> ControlResourceSetId (0..maxNrofControlReourceSets-1) (0..12-1) //uint32_t n_BWP_start = 0; //uint32_t n_rb_offset = 0; - uint32_t n_rb_offset = pdcch_vars2->coreset[nb_coreset_active].rb_offset;/*+(int)floor(frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB);*/ + uint32_t n_rb_offset = pdcch_vars2->coreset[nb_coreset_active].rb_offset;//+(int)floor(frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB); // start time position for CORESET // parameter symbol_mon is a 14 bits bitmap indicating monitoring symbols within a slot uint8_t start_symbol = 0; @@ -794,11 +827,9 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, } } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> symbol_mon=(%d) and start_symbol=(%d)\n",symbol_mon,start_symbol); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%ld) n_rb_offset=(%d) coreset_time_dur=(%d) n_shift=(%d) reg_bundle_size_L=(%d) coreset_interleaver_size_R=(%d) scrambling_ID=(%d) \n", + LOG_DD("symbol_mon=(%d) and start_symbol=(%d)\n",symbol_mon,start_symbol); + LOG_DD("coreset_freq_dom=(%ld) n_rb_offset=(%d) coreset_time_dur=(%d) n_shift=(%d) reg_bundle_size_L=(%d) coreset_interleaver_size_R=(%d) scrambling_ID=(%d) \n", coreset_freq_dom,n_rb_offset,coreset_time_dur,n_shift,reg_bundle_size_L,coreset_interleaver_size_R,pdcch_DMRS_scrambling_id); -#endif // // according to 38.213 v15.1.0: a PDCCH monitoring pattern within a slot, // indicating first symbol(s) of the control resource set within a slot @@ -814,9 +845,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, // for (int j=0; j < coreset_nbr_act; j++) { // for each active CORESET (max number of active CORESETs in a BWP is 3), // we calculate the number of RB for each CORESET bitmap -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%ld)\n",coreset_freq_dom); -#endif + LOG_DD("coreset_freq_dom=(%ld)\n",coreset_freq_dom); int i; //for each bit in the coreset_freq_dom bitmap for (i = 0; i < 45; i++) { @@ -825,22 +854,18 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, } coreset_nbr_rb = 6 * coreset_nbr_rb; // coreset_nbr_rb has to be multiplied by 6 to indicate the number of PRB or REG(=12 RE) within the CORESET -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%ld,%lx), coreset_nbr_rb=%d\n", coreset_freq_dom,coreset_freq_dom,coreset_nbr_rb); -#endif -#ifdef NR_PDCCH_DCI_DEBUG - uint8_t coreset_nbr_reg = coreset_time_dur * coreset_nbr_rb; - uint32_t coreset_C = (uint32_t)(coreset_nbr_reg / (reg_bundle_size_L * coreset_interleaver_size_R)); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_nbr_rb=%d, coreset_nbr_reg=%d, coreset_C=(%d/(%d*%d))=%d\n", - coreset_nbr_rb, coreset_nbr_reg, coreset_nbr_reg, reg_bundle_size_L,coreset_interleaver_size_R, coreset_C); -#endif + LOG_DD("coreset_freq_dom=(%ld,%lx), coreset_nbr_rb=%d\n", coreset_freq_dom,coreset_freq_dom,coreset_nbr_rb); + LOG_DD("coreset_nbr_rb=%d, coreset_nbr_reg=%d, coreset_C=(%d/(%d*%d))=%d\n", + coreset_nbr_rb, + coreset_time_dur * coreset_nbr_rb, + coreset_time_dur * coreset_nbr_rb, + reg_bundle_size_L,coreset_interleaver_size_R, + (uint32_t)((coreset_time_dur * coreset_nbr_rb) / (reg_bundle_size_L * coreset_interleaver_size_R)) ); for (int s = start_symbol; s < (start_symbol + coreset_time_dur); s++) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_extract_rbs_single(is_secondary_ue=%d) to remove DM-RS PDCCH\n", + LOG_DD("we enter nr_pdcch_extract_rbs_single(is_secondary_ue=%d) to remove DM-RS PDCCH\n", is_secondary_ue); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n"); -#endif + LOG_DD("in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n"); nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF, pdcch_vars[eNB_id]->dl_ch_estimates, pdcch_vars[eNB_id]->rxdataF_ext, @@ -851,10 +876,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, coreset_freq_dom, coreset_nbr_rb, n_rb_offset); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",avgP); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> in pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n"); -#endif + LOG_DD("we enter pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",*avgP); + LOG_DD("in pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n"); // compute channel level based on ofdm symbol 0 pdcch_channel_level(pdcch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, @@ -873,10 +896,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, T(T_UE_PHY_PDCCH_ENERGY, T_INT(eNB_id), T_INT(0), T_INT(frame%1024), T_INT(nr_tti_rx), T_INT(avgP[0]), T_INT(avgP[1]), T_INT(avgP[2]), T_INT(avgP[3])); #endif -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n"); -#endif + LOG_DD("we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh); + LOG_DD("in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n"); // compute LLRs for ofdm symbol 0 only nr_pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext, pdcch_vars[eNB_id]->dl_ch_estimates_ext, @@ -894,37 +915,31 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, #endif if (frame_parms->nb_antennas_rx > 1) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", + LOG_DD("we enter pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", frame_parms->nb_antennas_rx); -#endif pdcch_detection_mrc(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp,s); } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> in nr_pdcch_llr(rxdataF_comp -> llr)\n"); -#endif + LOG_DD("we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s); + LOG_DD("in nr_pdcch_llr(rxdataF_comp -> llr)\n"); nr_pdcch_llr(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp, pdcch_vars[eNB_id]->llr, s, coreset_nbr_rb); #if T_TRACER - /* - T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL), - T_INT(n_pdcch_symbols), - T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4)); - */ + + // T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL), + // T_INT(n_pdcch_symbols), + // T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4)); + #endif #ifdef DEBUG_DCI_DECODING printf("demapping: nr_tti_rx %d, mi %d\n",nr_tti_rx,get_mi(frame_parms,nr_tti_rx)); #endif } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_demapping_deinterleaving()\n"); -#endif + LOG_DD("we enter nr_pdcch_demapping_deinterleaving()\n"); nr_pdcch_demapping_deinterleaving((uint32_t *) pdcch_vars[eNB_id]->llr, (uint32_t *) pdcch_vars[eNB_id]->e_rx, frame_parms, @@ -941,14 +956,11 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, // get_nCCE(n_pdcch_symbols, frame_parms, mi) * 72, pdcch_DMRS_scrambling_id, do_common); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we end nr_pdcch_unscrambling()\n"); -#endif -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> Ending nr_rx_pdcch() function\n"); -#endif + LOG_DD("we end nr_pdcch_unscrambling()\n"); + LOG_DD("Ending nr_rx_pdcch() function\n"); return (0); } + */ #endif @@ -980,70 +992,28 @@ void pdcch_scrambling(NR_DL_FRAME_PARMS *frame_parms, #ifdef NR_PDCCH_DCI_RUN -void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t nr_tti_rx, - int16_t *z, uint32_t length, uint16_t pdcch_DMRS_scrambling_id, int do_common) { +void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t slot, + int16_t *z, uint32_t length, uint16_t pdcch_DMRS_scrambling_id) { int i; uint8_t reset; uint32_t x1, x2, s = 0; uint16_t n_id; //{0,1,...,65535} uint32_t n_rnti; reset = 1; - // x1 is set in first call to lte_gold_generic //do_common=1; - if (do_common) { - n_id = frame_parms->Nid_cell; - n_rnti = 0; - } else { n_id = pdcch_DMRS_scrambling_id; n_rnti = (uint32_t)crnti; - } - //x2 = ((n_rnti * (1 << 16)) + n_id)%(1 << 31); - //uint32_t puissance_2_16 = ((1<<16)*n_rnti)+n_id; - //uint32_t puissance_2_31= (1<<30)*2; - //uint32_t calc_x2=puissance_2_16%puissance_2_31; x2 = (((1<<16)*n_rnti)+n_id); //mod 2^31 is implicit //this is c_init in 38.211 v15.1.0 Section 7.3.2.3 - // x2 = (nr_tti_rx << 9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 -#ifdef NR_PDCCH_DCI_DEBUG - //printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> (c_init=%d, n_id=%d, n_rnti=%d, length=%d)\n",x2,n_id,n_rnti,length); -#endif for (i = 0; i < length; i++) { if ((i & 0x1f) == 0) { s = lte_gold_generic(&x1, &x2, reset); - //printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> lte_gold[%d]=%x\n",i,s); reset = 0; } - /* - #ifdef NR_PDCCH_DCI_DEBUG - if (i%2 == 0) printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> unscrambling %d : scrambled_z=%d, => ", - i,*(char*) &z[(int)floor(i/2)]); - if (i%2 == 1) printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> unscrambling %d : scrambled_z=%d, => ", - i,*(1 + (char*) &z[(int)floor(i/2)])); - #endif - if (((s >> (i % 32)) & 1) == 1){ - if (i%2 == 0) *(char*) &z[(int)floor(i/2)] = -(*(char*) &z[(int)floor(i/2)]); - if (i%2 == 1) *(1 + (char*) &z[(int)floor(i/2)]) = -(*(1 + (char*) &z[(int)floor(i/2)])); - } - //llr[i] = -llr[i]; - //llr[i] = (-1)*llr[i]; - #ifdef NR_PDCCH_DCI_DEBUG - if (i%2 == 0) printf("unscrambled_z=%d\n",*(char*) &z[(int)floor(i/2)]); - if (i%2 == 1) printf("unscrambled_z=%d\n",*(1 + (char*) &z[(int)floor(i/2)])); - #endif - */ -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> unscrambling %d : scrambled_z=%d, => ", - i,z[i]); -#endif - if (((s >> (i % 32)) & 1) == 1) z[i] = -z[i]; - -#ifdef NR_PDCCH_DCI_DEBUG - printf("unscrambled_z=%d\n",z[i]); -#endif } } @@ -1051,6 +1021,42 @@ void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8 #ifdef NR_PDCCH_DCI_RUN +uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, + int frame, + int slot, + fapi_nr_dci_indication_t *dci_ind) { + + NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[slot]][0]; + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15; + for (int i=0;i nb_search_space;i++) { + + rel15 = &pdcch_vars->pdcch_config[i]; + int dci_length = rel15->dci_length; + for (int j=0;j number_of_candidates;j++) { + int CCEind = rel15->CCE[j]; + int L = rel15->L[j]; + uint64_t dci_estimation[2]= {0}; + const t_nrPolar_params *currentPtrDCI=nr_polar_params(1, dci_length, L,1,&ue->polarList); + uint16_t crc = polar_decoder_int16(&pdcch_vars->e_rx[CCEind*9*6*2], + dci_estimation, + 1, + currentPtrDCI); + if (crc == rel15->rnti) { + dci_ind->SFN = frame; + dci_ind->slot = slot; + dci_ind->dci_list[dci_ind->number_of_dcis].rnti = rel15->rnti; + dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE = CCEind; + dci_ind->dci_list[dci_ind->number_of_dcis].dci_format = rel15->dci_format; + dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length; + memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8); + dci_ind->number_of_dcis++; + } + } + } + return(dci_ind->number_of_dcis); +} + +/* void nr_dci_decoding_procedure0(int s, int p, int coreset_time_dur, @@ -1089,19 +1095,15 @@ void nr_dci_decoding_procedure0(int s, //Table 10.1-3: Maximum number of non-overlapped CCEs per slot and per serving cell as a function of the subcarrier spacing value 2^mu*15 KHz, mu {0,1,2,3} //uint8_t cce_max_slot_pdcch_Table10_1_3 [4] = {56,56,48,32}; int coreset_nbr_cce_per_symbol=0; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> format_found is %d \n", *format_found); -#endif + LOG_DDD("format_found is %d \n", *format_found); //if (mode == NO_DCI) { // #ifdef NR_PDCCH_DCI_DEBUG - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> skip DCI decoding: expect no DCIs at nr_tti_rx %d in current searchSpace\n", nr_tti_rx); + // LOG_DDD("skip DCI decoding: expect no DCIs at nr_tti_rx %d in current searchSpace\n", nr_tti_rx); // #endif // return; //} -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> frequencyDomainResources=%lx, duration=%d\n", + LOG_DDD("frequencyDomainResources=%lx, duration=%d\n", pdcch_vars[eNB_id]->coreset[p].frequencyDomainResources, pdcch_vars[eNB_id]->coreset[p].duration); -#endif // nCCE = get_nCCE(pdcch_vars[eNB_id]->num_pdcch_symbols, frame_parms, mi); for (int i = 0; i < 45; i++) { @@ -1115,28 +1117,26 @@ void nr_dci_decoding_procedure0(int s, // the number of symbols in the CORESET (pdcch_vars[eNB_id]->coreset[p].duration) // multiplied by the number of bits set to '1' in the frequencyDomainResources bitmap // (1 bit set to '1' corresponds to 6 RB and 1 CCE = 6 RB) -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> nCCE[%d]=%d\n",p,nCCE[p]); -#endif + LOG_DDD("nCCE[%d]=%d\n",p,nCCE[p]); - /* if (nCCE > get_nCCE(3, frame_parms, 1)) { - LOG_D(PHY, - "skip DCI decoding: nCCE=%d > get_nCCE(3,frame_parms,1)=%d\n", - nCCE, get_nCCE(3, frame_parms, 1)); - return; - } + // if (nCCE > get_nCCE(3, frame_parms, 1)) { + //LOG_D(PHY, + //"skip DCI decoding: nCCE=%d > get_nCCE(3,frame_parms,1)=%d\n", + //nCCE, get_nCCE(3, frame_parms, 1)); + //return; + // } - if (nCCE < L2) { - LOG_D(PHY, "skip DCI decoding: nCCE=%d < L2=%d\n", nCCE, L2); - return; - } +// if (nCCE < L2) { +// LOG_D(PHY, "skip DCI decoding: nCCE=%d < L2=%d\n", nCCE, L2); +// return; +// } + +// if (mode == NO_DCI) { +// LOG_D(PHY, "skip DCI decoding: expect no DCIs at nr_tti_rx %d\n", +// nr_tti_rx); +// return; +// } - if (mode == NO_DCI) { - LOG_D(PHY, "skip DCI decoding: expect no DCIs at nr_tti_rx %d\n", - nr_tti_rx); - return; - } - */ if (do_common == 1) { Yk = 0; @@ -1171,9 +1171,7 @@ void nr_dci_decoding_procedure0(int s, nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.srs_nrofCandidates; } else { nb_candidates = (L2 == 4) ? 4 : ((L2 == 8)? 2 : 1); // according to Table 10.1-1 (38.213 section 10.1) -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> we are in common searchSpace and nb_candidates=%d for L2=%d\n",nb_candidates,L2); -#endif + LOG_DDD("we are in common searchSpace and nb_candidates=%u for L2=%d\n", nb_candidates, L2); } } else { switch (L2) { @@ -1210,12 +1208,10 @@ void nr_dci_decoding_procedure0(int s, Yk = (Yk * A[p%3]) % 65537; } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> L2(%d) | nCCE[%d](%d) | Yk(%d) | nb_candidates(%d)\n",L2,p,nCCE[p],Yk,nb_candidates); -#endif - /* for (CCEind=0; - CCEind nCCE[p]) // nb_candidates = nCCE[p] / L2; // In the next code line there is maybe a bug. The spec is not comparing Table 10.1-2 with nb_candidates, but with total number of candidates for all s and all p @@ -1223,27 +1219,19 @@ void nr_dci_decoding_procedure0(int s, if (L==4) m_p_s_L_max=1; // Table 10.1-2 is not defined for L=4 -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> m_max_slot_pdcch_Table10_1_2(%d)=%d\n",L,m_max_slot_pdcch_Table10_1_2[L]); -#endif + if(0 <= L && L < 4) LOG_DDD("m_max_slot_pdcch_Table10_1_2(%d)=%d\n",L,m_max_slot_pdcch_Table10_1_2[L]); for (m = 0; m < nb_candidates; m++) { int n_ci = 0; if (nCCE[p] < L2) return; -#ifdef NR_PDCCH_DCI_DEBUG - int debug1 = nCCE[p] / L2; - int debug2 = L2*m_p_s_L_max; - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> debug1(%d)=nCCE[p]/L2 | nCCE[%d](%d) | L2(%d)\n",debug1,p,nCCE[p],L2); - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> debug2(%d)=L2*m_p_s_L_max | L2(%d) | m_p_s_L_max(%d)\n",debug2,L2,m_p_s_L_max); -#endif - CCEind = (((Yk + (uint16_t)(floor((m*nCCE[p])/(L2*m_p_s_L_max))) + n_ci) % (uint16_t)(floor(nCCE[p] / L2))) * L2); -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> CCEind(%d) = (((Yk(%d) + ((m(%d)*nCCE[p](%d))/(L2(%d)*m_p_s_L_max(%d)))) % (nCCE[p] / L2)) * L2)\n", + LOG_DDD("debug1(%d)=nCCE[p]/L2 | nCCE[%d](%d) | L2(%d)\n",nCCE[p] / L2,p,nCCE[p],L2); + LOG_DDD("debug2(%d)=L2*m_p_s_L_max | L2(%d) | m_p_s_L_max(%d)\n",L2*m_p_s_L_max,L2,m_p_s_L_max); + CCEind = (((Yk + (uint16_t)(floor((m*nCCE[p])/(L2*m_p_s_L_max))) + n_ci) % (uint16_t)(floor(nCCE[p] / L2))) * L2); + LOG_DDD("CCEind(%d) = (((Yk(%u) + ((m(%u)*nCCE[p](%d))/(L2(%d)*m_p_s_L_max(%d)))) %% (nCCE[p] / L2)) * L2)\n", CCEind,Yk,m,nCCE[p],L2,m_p_s_L_max); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> n_candidate(m)=%d | CCEind=%d |",m,CCEind); -#endif + LOG_DDD("n_candidate(m)=%u | CCEind=%d |",m,CCEind); if (CCEind < 32) CCEmap = CCEmap0; @@ -1251,7 +1239,7 @@ void nr_dci_decoding_procedure0(int s, CCEmap = CCEmap1; else if (CCEind < 96) CCEmap = CCEmap2; - else AssertFatal(1==0,"Illegal CCEind %d (Yk %d, m %d, nCCE %d, L2 %d\n",CCEind, Yk, m, nCCE[p], L2); + else AssertFatal(1==0,"Illegal CCEind %d (Yk %u, m %u, nCCE %d, L2 %d\n", CCEind, Yk, m, nCCE[p], L2); switch (L2) { case 1: @@ -1282,9 +1270,7 @@ void nr_dci_decoding_procedure0(int s, CCEmap_cand = (*CCEmap) & CCEmap_mask; // CCE is not allocated yet -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> CCEmap_cand=%d \n",CCEmap_cand); -#endif + LOG_DDD("CCEmap_cand=%u \n",CCEmap_cand); if (CCEmap_cand == 0) { #ifdef DEBUG_DCI_DECODING @@ -1297,60 +1283,53 @@ void nr_dci_decoding_procedure0(int s, pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_uss); #endif -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we enter function dci_decoding(sizeof_bits=%d L=%d) -----\n",sizeof_bits,L); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we have to replace this part of the code by polar decoding\n"); -#endif + LOG_DDD("... we enter function dci_decoding(sizeof_bits=%d L=%d) -----\n",sizeof_bits,L); + LOG_DDD("... we have to replace this part of the code by polar decoding\n"); // for (int m=0; m < (nCCE[p]*6*9*2); m++) -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0: polar decoding)-> polar intput (with coreset_time_dur=%d, coreset_nbr_rb=%d, p=%d, CCEind=%d): \n", + LOG_DDD("(polar decoding)-> polar intput (with coreset_time_dur=%d, coreset_nbr_rb=%d, p=%d, CCEind=%d): \n", coreset_time_dur,coreset_nbr_rb,p,CCEind); -#endif - /* - int reg_p=0,reg_e=0; - for (int m=0; m < (L2*6); m++){ - reg_p = (((int)floor(m/coreset_time_dur))+((m%coreset_time_dur)*(L2*6/coreset_time_dur)))*9*2; - reg_e = m*9*2; - for (int i=0; i<9*2; i++){ + + //int reg_p=0,reg_e=0; + //for (int m=0; m < (L2*6); m++){ + //reg_p = (((int)floor(m/coreset_time_dur))+((m%coreset_time_dur)*(L2*6/coreset_time_dur)))*9*2; + //reg_e = m*9*2; + //for (int i=0; i<9*2; i++){ //polar_input[reg_p+i] = (pdcch_vars[eNB_id]->e_rx[((CCEind*9*6*2) + reg_e + i)]>0) ? (1.0):(-1.0); - polar_input[reg_e+i] = (pdcch_vars[eNB_id]->e_rx[((CCEind*9*6*2) + reg_e + i)]>0) ? (1/sqrt(2)):((-1)/sqrt(2)); + //polar_input[reg_e+i] = (pdcch_vars[eNB_id]->e_rx[((CCEind*9*6*2) + reg_e + i)]>0) ? (1/sqrt(2)):((-1)/sqrt(2)); //printf("\t m=%d \tpolar_input[%d]=%lf <-> e_rx[%d]=%d\n",m,reg_e+i,polar_input[reg_e+i], // ((CCEind*9*6*2) + reg_e + i),pdcch_vars[eNB_id]->e_rx[((CCEind*9*6*2) + reg_e + i)]); //printf("\t m=%d \tpolar_input[%d]=%lf <-> e_rx[%d]=%d\n",m,reg_p+i,polar_input[reg_p+i], // ((CCEind*9*6*2) + reg_e + i),pdcch_vars[eNB_id]->e_rx[((CCEind*9*6*2) + reg_e + i)]); - } - } + //} + //} - #ifdef NR_PDCCH_DCI_DEBUG - printf("\n"); - int j=0; - uint32_t polar_hex[27] = {0}; - for (int i=0; i polar_hex[%d]=%x\n",j,polar_hex[j]); - #endif - */ + //polar_hex[j] = polar_hex[j] + (((polar_input[i]==((-1)/sqrt(2)))?1:0)<<(i%32)); + //} + //for (j=0;j<27;j++) LOG_DDD("polar_hex[%d]=%x\n",j,polar_hex[j]); + //#endif + uint64_t dci_estimation[2]= {0}; - const t_nrPolar_params *currentPtrDCI=nr_polar_params(1, sizeof_bits, L2); + const t_nrPolar_params *currentPtrDCI=nr_polar_params(1, sizeof_bits, L2,1); decoderState = polar_decoder_int16(&pdcch_vars[eNB_id]->e_rx[CCEind*9*6*2], dci_estimation, + 1, currentPtrDCI); crc = decoderState; //crc = (crc16(&dci_decoded_output[current_thread_id][0], sizeof_bits) >> 16) ^ extract_crc(&dci_decoded_output[current_thread_id][0], sizeof_bits); -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we end function dci_decoding() with crc=%x\n",crc); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we have to replace this part of the code by polar decoding\n"); -#endif + LOG_DDD("... we end function dci_decoding() with crc=%x\n",crc); + LOG_DDD("... we have to replace this part of the code by polar decoding\n"); #ifdef DEBUG_DCI_DECODING - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0: crc =>%d\n",crc); + LOG_DDD("(nr_dci_decoding_procedure0: crc =>%d\n",crc); #endif //uint16_t tc_rnti, uint16_t int_rnti, uint16_t sfi_rnti, uint16_t tpc_pusch_rnti, uint16_t tpc_pucch_rnti, uint16_t tpc_srs__rnti -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> format_found=%d\n",*format_found); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> crc_scrambled=%d\n",*crc_scrambled); -#endif + LOG_DDD("format_found=%d\n",*format_found); + LOG_DDD("crc_scrambled=%d\n",*crc_scrambled); if (crc == crc_scrambled_values[_C_RNTI_]) { *crc_scrambled =_c_rnti; @@ -1418,10 +1397,8 @@ void nr_dci_decoding_procedure0(int s, } -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> format_found=%d\n",*format_found); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> crc_scrambled=%d\n",*crc_scrambled); -#endif + LOG_DDD("format_found=%d\n",*format_found); + LOG_DDD("crc_scrambled=%d\n",*crc_scrambled); if (*format_found!=255) { dci_alloc[*dci_cnt].dci_length = sizeof_bits; @@ -1430,31 +1407,29 @@ void nr_dci_decoding_procedure0(int s, dci_alloc[*dci_cnt].firstCCE = CCEind; memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_estimation,8); -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> rnti matches -> DCI FOUND !!! crc =>0x%x, sizeof_bits %d, sizeof_bytes %d \n", + LOG_DDD("rnti matches -> DCI FOUND !!! crc =>0x%x, sizeof_bits %d, sizeof_bytes %d \n", dci_alloc[*dci_cnt].rnti, dci_alloc[*dci_cnt].dci_length, sizeof_bytes); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> dci_cnt %d (format_css %d crc_scrambled %d) L %d, firstCCE %d pdu[0] 0x%lx pdu[1] 0x%lx \n", + LOG_DDD("dci_cnt %d (format_css %d crc_scrambled %d) L %d, firstCCE %d pdu[0] 0x%lx pdu[1] 0x%lx \n", *dci_cnt, format_css,*crc_scrambled,dci_alloc[*dci_cnt].L, dci_alloc[*dci_cnt].firstCCE,dci_alloc[*dci_cnt].dci_pdu[0],dci_alloc[*dci_cnt].dci_pdu[1]); -#endif if ((format_css == cformat0_0_and_1_0) || (format_uss == uformat0_0_and_1_0)) { if ((*crc_scrambled == _p_rnti) || (*crc_scrambled == _si_rnti) || (*crc_scrambled == _ra_rnti)) { dci_alloc[*dci_cnt].format = format1_0; *dci_cnt = *dci_cnt + 1; *format_found=_format_1_0_found; - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> a format1_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); + // LOG_DDD("a format1_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); } else { if ((dci_estimation[0]&1) == 0) { dci_alloc[*dci_cnt].format = format0_0; *dci_cnt = *dci_cnt + 1; *format_found=_format_0_0_found; - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> b format0_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); + // LOG_DDD("b format0_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); } if ((dci_estimation[0]&1) == 1) { dci_alloc[*dci_cnt].format = format1_0; *dci_cnt = *dci_cnt + 1; *format_found=_format_1_0_found; - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> c format1_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); + // LOG_DDD("c format1_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); } } } @@ -1500,42 +1475,42 @@ void nr_dci_decoding_procedure0(int s, // store first nCCE of group for PUCCH transmission of ACK/NAK pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; - /* if (crc == si_rnti) { - dci_alloc[*dci_cnt].format = format_si; - *dci_cnt = *dci_cnt + 1; - } else if (crc == p_rnti) { - dci_alloc[*dci_cnt].format = format_p; - *dci_cnt = *dci_cnt + 1; - } else if (crc == ra_rnti) { - dci_alloc[*dci_cnt].format = format_ra; - // store first nCCE of group for PUCCH transmission of ACK/NAK - pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; - *dci_cnt = *dci_cnt + 1; - } else if (crc == pdcch_vars[eNB_id]->crnti) { + // if (crc == si_rnti) { + // dci_alloc[*dci_cnt].format = format_si; + // *dci_cnt = *dci_cnt + 1; + // } else if (crc == p_rnti) { + // dci_alloc[*dci_cnt].format = format_p; + // *dci_cnt = *dci_cnt + 1; + // } else if (crc == ra_rnti) { + // dci_alloc[*dci_cnt].format = format_ra; + // // store first nCCE of group for PUCCH transmission of ACK/NAK + // pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; + // *dci_cnt = *dci_cnt + 1; + // } else if (crc == pdcch_vars[eNB_id]->crnti) { - if ((mode & UL_DCI) && (format_c == format0) - && ((dci_decoded_output[current_thread_id][0] & 0x80) - == 0)) { // check if pdu is format 0 or 1A - if (*format0_found == 0) { - dci_alloc[*dci_cnt].format = format0; - *format0_found = 1; - *dci_cnt = *dci_cnt + 1; - pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; - } - } else if (format_c == format0) { // this is a format 1A DCI - dci_alloc[*dci_cnt].format = format1A; - *dci_cnt = *dci_cnt + 1; - pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; - } else { - // store first nCCE of group for PUCCH transmission of ACK/NAK - if (*format_c_found == 0) { - dci_alloc[*dci_cnt].format = format_c; - *dci_cnt = *dci_cnt + 1; - *format_c_found = 1; - pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; - } - } - }*/ + // if ((mode & UL_DCI) && (format_c == format0) + // && ((dci_decoded_output[current_thread_id][0] & 0x80) + // == 0)) { // check if pdu is format 0 or 1A + // if (*format0_found == 0) { + // dci_alloc[*dci_cnt].format = format0; + // *format0_found = 1; + // *dci_cnt = *dci_cnt + 1; + // pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; + // } + // } else if (format_c == format0) { // this is a format 1A DCI + // dci_alloc[*dci_cnt].format = format1A; + // *dci_cnt = *dci_cnt + 1; + // pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; + // } else { + // // store first nCCE of group for PUCCH transmission of ACK/NAK + // if (*format_c_found == 0) { + // dci_alloc[*dci_cnt].format = format_c; + // *dci_cnt = *dci_cnt + 1; + // *format_c_found = 1; + // pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; + // } + // } + // } //LOG_I(PHY,"DCI decoding CRNTI [format: %d, nCCE[nr_tti_rx: %d]: %d ], AggregationLevel %d \n",format_c, nr_tti_rx, pdcch_vars[eNB_id]->nCCE[nr_tti_rx],L2); // memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes); switch (1 << L) { @@ -1572,1057 +1547,30 @@ void nr_dci_decoding_procedure0(int s, printf("\n"); } - /* - if ( agregationLevel != 0xFF && - (format_c == format0 && m==0 && si_rnti != SI_RNTI)) - { - //Only valid for OAI : Save some processing time when looking for DCI format0. From the log we see the DCI only on candidate 0. - return; - } - */ + + // if ( agregationLevel != 0xFF && + // (format_c == format0 && m==0 && si_rnti != SI_RNTI)) + // { + // //Only valid for OAI : Save some processing time when looking for DCI format0. From the log we see the DCI only on candidate 0. + // return; + // } + } // candidate loop -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> end candidate loop\n"); -#endif + LOG_DDD("end candidate loop\n"); } - -#endif - - - - - -/*void dci_decoding_procedure0(NR_UE_PDCCH **pdcch_vars, - int do_common, - dci_detect_mode_t mode, - uint8_t nr_tti_rx, - DCI_ALLOC_t *dci_alloc, - int16_t eNB_id, - uint8_t current_thread_id, - NR_DL_FRAME_PARMS *frame_parms, - uint8_t mi, - uint16_t si_rnti, - uint16_t ra_rnti, - uint16_t p_rnti, - uint8_t L, - uint8_t format_si, - uint8_t format_p, - uint8_t format_ra, - uint8_t format_c, - uint8_t sizeof_bits, - uint8_t sizeof_bytes, - uint8_t *dci_cnt, - uint8_t *format0_found, - uint8_t *format_c_found, - uint32_t *CCEmap0, - uint32_t *CCEmap1, - uint32_t *CCEmap2) - { - - uint16_t crc,CCEind,nCCE; - uint32_t *CCEmap=NULL,CCEmap_mask=0; - int L2=(1< \n"); - #endif - nCCE = get_nCCE(pdcch_vars[eNB_id]->num_pdcch_symbols,frame_parms,mi); - - if (nCCE > get_nCCE(3,frame_parms,1)) { - LOG_D(PHY,"skip DCI decoding: nCCE=%d > get_nCCE(3,frame_parms,1)=%d\n", nCCE, get_nCCE(3,frame_parms,1)); - return; - } - - if (nCCE crnti; - - for (i=0; i<=nr_tti_rx; i++) - Yk = (Yk*39827)%65537; - - Yk = Yk % (nCCE/L2); - - switch (L2) { - case 1: - case 2: - nb_candidates = 6; - break; - - case 4: - case 8: - nb_candidates = 2; - break; - - default: - DevParam(L2, do_common, eNB_id); - break; - } - } - - // for (CCEind=0; - // CCEind nCCE) - nb_candidates = nCCE/L2; - - for (m=0; m macphy_exit("Illegal CCEind\n"); - return; // not reached - } - - switch (L2) { - case 1: - CCEmap_mask = (1<<(CCEind&0x1f)); - break; - - case 2: - CCEmap_mask = (3<<(CCEind&0x1f)); - break; - - case 4: - CCEmap_mask = (0xf<<(CCEind&0x1f)); - break; - - case 8: - CCEmap_mask = (0xff<<(CCEind&0x1f)); - break; - - default: - LOG_E( PHY, "Illegal L2 value %d\n", L2 ); - mac_xface->macphy_exit( "Illegal L2\n" ); - return; // not reached - } - - CCEmap_cand = (*CCEmap)&CCEmap_mask; - - // CCE is not allocated yet - - if (CCEmap_cand == 0) { - #ifdef DEBUG_DCI_DECODING - - if (do_common == 1) - LOG_I(PHY,"[DCI search nPdcch %d - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n", - pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask); - else - LOG_I(PHY,"[DCI search nPdcch %d - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n", - pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_c); - - #endif - - dci_decoding(sizeof_bits, - L, - &pdcch_vars[eNB_id]->e_rx[CCEind*72], - &dci_decoded_output[current_thread_id][0]); - - // for (i=0;i<3+(sizeof_bits>>3);i++) - // printf("dci_decoded_output[%d] => %x\n",i,dci_decoded_output[i]); - - crc = (crc16(&dci_decoded_output[current_thread_id][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[current_thread_id][0],sizeof_bits); - #ifdef DEBUG_DCI_DECODING - printf("crc =>%x\n",crc); - #endif - - if (((L>1) && ((crc == si_rnti)|| (crc == p_rnti)|| (crc == ra_rnti)))|| - (crc == pdcch_vars[eNB_id]->crnti)) { - dci_alloc[*dci_cnt].dci_length = sizeof_bits; - dci_alloc[*dci_cnt].rnti = crc; - dci_alloc[*dci_cnt].L = L; - dci_alloc[*dci_cnt].firstCCE = CCEind; - - //printf("DCI FOUND !!! crc =>%x, sizeof_bits %d, sizeof_bytes %d \n",crc, sizeof_bits, sizeof_bytes); - if (sizeof_bytes<=4) { - dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][0]; - dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][1]; - dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][2]; - dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][3]; - #ifdef DEBUG_DCI_DECODING - printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[current_thread_id][0], - dci_decoded_output[current_thread_id][1], - dci_decoded_output[current_thread_id][2], - dci_decoded_output[current_thread_id][3]); - #endif - } else { - dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[current_thread_id][0]; - dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[current_thread_id][1]; - dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[current_thread_id][2]; - dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[current_thread_id][3]; - dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][4]; - dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][5]; - dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][6]; - dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][7]; - #ifdef DEBUG_DCI_DECODING - printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n", - dci_decoded_output[current_thread_id][0],dci_decoded_output[current_thread_id][1],dci_decoded_output[current_thread_id][2],dci_decoded_output[current_thread_id][3], - dci_decoded_output[current_thread_id][4],dci_decoded_output[current_thread_id][5],dci_decoded_output[current_thread_id][6],dci_decoded_output[current_thread_id][7]); - #endif - } - - if (crc==si_rnti) { - dci_alloc[*dci_cnt].format = format_si; - *dci_cnt = *dci_cnt+1; - } else if (crc==p_rnti) { - dci_alloc[*dci_cnt].format = format_p; - *dci_cnt = *dci_cnt+1; - } else if (crc==ra_rnti) { - dci_alloc[*dci_cnt].format = format_ra; - // store first nCCE of group for PUCCH transmission of ACK/NAK - pdcch_vars[eNB_id]->nCCE[nr_tti_rx]=CCEind; - *dci_cnt = *dci_cnt+1; - } else if (crc==pdcch_vars[eNB_id]->crnti) { - - if ((mode&UL_DCI)&&(format_c == format0)&&((dci_decoded_output[current_thread_id][0]&0x80)==0)) {// check if pdu is format 0 or 1A - if (*format0_found == 0) { - dci_alloc[*dci_cnt].format = format0; - *format0_found = 1; - *dci_cnt = *dci_cnt+1; - pdcch_vars[eNB_id]->nCCE[nr_tti_rx]=CCEind; - } - } else if (format_c == format0) { // this is a format 1A DCI - dci_alloc[*dci_cnt].format = format1A; - *dci_cnt = *dci_cnt+1; - pdcch_vars[eNB_id]->nCCE[nr_tti_rx]=CCEind; - } else { - // store first nCCE of group for PUCCH transmission of ACK/NAK - if (*format_c_found == 0) { - dci_alloc[*dci_cnt].format = format_c; - *dci_cnt = *dci_cnt+1; - *format_c_found = 1; - pdcch_vars[eNB_id]->nCCE[nr_tti_rx]=CCEind; - } - } - } - - //LOG_I(PHY,"DCI decoding CRNTI [format: %d, nCCE[nr_tti_rx: %d]: %d ], AggregationLevel %d \n",format_c, nr_tti_rx, pdcch_vars[eNB_id]->nCCE[nr_tti_rx],L2); - // memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes); - - - - switch (1< pdcch_vars[ue->current_thread_id[nr_tti_rx]]; - NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - uint8_t mi = get_mi(&ue->frame_parms,nr_tti_rx); - uint16_t ra_rnti=99; - uint8_t format0_found=0,format_c_found=0; - uint8_t tmode = ue->transmission_mode[eNB_id]; - uint8_t frame_type = frame_parms->frame_type; - uint8_t format0_size_bits=0,format0_size_bytes=0; - uint8_t format1_size_bits=0,format1_size_bytes=0; - dci_detect_mode_t mode = dci_detect_mode_select(&ue->frame_parms,nr_tti_rx); - - switch (frame_parms->N_RB_DL) { - case 6: - if (frame_type == TDD) { - format0_size_bits = sizeof_DCI0_1_5MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_1_5MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_1_5MHz_TDD_t); - - } else { - format0_size_bits = sizeof_DCI0_1_5MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_1_5MHz_FDD_t); - format1_size_bits = sizeof_DCI1_1_5MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_1_5MHz_FDD_t); - } - - break; - - case 25: - default: - if (frame_type == TDD) { - format0_size_bits = sizeof_DCI0_5MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_5MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_5MHz_TDD_t); - } else { - format0_size_bits = sizeof_DCI0_5MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_5MHz_FDD_t); - format1_size_bits = sizeof_DCI1_5MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_5MHz_FDD_t); - } - - break; - - case 50: - if (frame_type == TDD) { - format0_size_bits = sizeof_DCI0_10MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_10MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_10MHz_TDD_t); - - } else { - format0_size_bits = sizeof_DCI0_10MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_10MHz_FDD_t); - format1_size_bits = sizeof_DCI1_10MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_10MHz_FDD_t); - } - - break; - - case 100: - if (frame_type == TDD) { - format0_size_bits = sizeof_DCI0_20MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_20MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_20MHz_TDD_t); - } else { - format0_size_bits = sizeof_DCI0_20MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_20MHz_FDD_t); - format1_size_bits = sizeof_DCI1_20MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_20MHz_FDD_t); - } - - break; - } - - if (ue->prach_resources[eNB_id]) - ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI; - - // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8 - dci_decoding_procedure0(pdcch_vars,0,mode, - nr_tti_rx, - dci_alloc, - eNB_id, - ue->current_thread_id[nr_tti_rx], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - agregationLevel, - format1A, - format1A, - format1A, - format0, - format0_size_bits, - format0_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - if (DCIFormat == 1) - { - if ((tmode < 3) || (tmode == 7)) { - //printf("Crnti decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat); - - // Now check UE_SPEC format 1 search spaces at aggregation 1 - - //printf("[DCI search] Format 1/1A aggregation 1\n"); - - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode,nr_tti_rx, - dci_alloc, - eNB_id, - ue->current_thread_id[nr_tti_rx], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 0, - format1A, - format1A, - format1A, - format1, - format1_size_bits, - format1_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff) || - (format_c_found==1)) - return(dci_cnt); - - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - //printf("Crnti 1 decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat); - - } - else - { - AssertFatal(0,"Other Transmission mode not yet coded\n"); - } - } - else - { - AssertFatal(0,"DCI format %d not yet implemented \n",DCIFormat); - } - - return(dci_cnt); - - } */ - -#ifdef NR_PDCCH_DCI_RUN - -uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, - uint16_t eNB_id, - uint8_t nr_tti_rx, - int p, - crc_scrambled_t crc_scrambled, - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - uint8_t format) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size)-> crc_scrambled=%d, n_RB_ULBWP=%d, n_RB_DLBWP=%d\n",crc_scrambled,n_RB_ULBWP,n_RB_DLBWP); -#endif - /* - * function nr_dci_format_size calculates and returns the size in bits of a determined format - * it also returns an bi-dimensional array 'dci_fields_sizes' with x rows and y columns, where: - * x is the number of fields defined in TS 38.212 subclause 7.3.1 (Each field is mapped in the order in which it appears in the description in the specification) - * y is the number of formats - * e.g.: dci_fields_sizes[10][0] contains the size in bits of the field FREQ_DOM_RESOURCE_ASSIGNMENT_UL for format 0_0 - */ - // pdsch_config contains the PDSCH-Config IE is used to configure the UE specific PDSCH parameters (TS 38.331) - PDSCH_Config_t pdsch_config = ue->PDSCH_Config; - // pusch_config contains the PUSCH-Config IE is used to configure the UE specific PUSCH parameters (TS 38.331) - PUSCH_Config_t pusch_config = ue->pusch_config; - PUCCH_Config_t pucch_config_dedicated = ue->pucch_config_dedicated_nr[eNB_id]; - crossCarrierSchedulingConfig_t crossCarrierSchedulingConfig = ue->crossCarrierSchedulingConfig; - dmrs_UplinkConfig_t dmrs_UplinkConfig = ue->dmrs_UplinkConfig; - dmrs_DownlinkConfig_t dmrs_DownlinkConfig = ue->dmrs_DownlinkConfig; - csi_MeasConfig_t csi_MeasConfig = ue->csi_MeasConfig; - PUSCH_ServingCellConfig_t PUSCH_ServingCellConfig= ue->PUSCH_ServingCellConfig; - PDSCH_ServingCellConfig_t PDSCH_ServingCellConfig= ue->PDSCH_ServingCellConfig; - NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]; - // 1 CARRIER_IN - // crossCarrierSchedulingConfig from higher layers, variable crossCarrierSchedulingConfig indicates if 'cross carrier scheduling' is enabled or not: - // if No cross carrier scheduling: number of bits for CARRIER_IND is 0 - // if Cross carrier scheduling: number of bits for CARRIER_IND is 3 - // The IE CrossCarrierSchedulingConfig is used to specify the configuration when the cross-carrier scheduling is used in a cell - uint8_t crossCarrierSchedulingConfig_ind = 0; - - if (crossCarrierSchedulingConfig.schedulingCellInfo.other.cif_InSchedulingCell !=0 ) crossCarrierSchedulingConfig_ind=1; - - // 2 SUL_IND_0_1, // 40 SRS_REQUEST, // 50 SUL_IND_0_0 - // UL/SUL indicator (TS 38.331, supplementary uplink is indicated in higher layer parameter ServCellAdd-SUL from IE ServingCellConfig and ServingCellConfigCommon): - // 0 bit for UEs not configured with SUL in the cell or UEs configured with SUL in the cell but only PUCCH carrier in the cell is configured for PUSCH transmission - // 1 bit for UEs configured with SUL in the cell as defined in Table 7.3.1.1.1-1 - // sul_ind indicates whether SUL is configured in cell or not - uint8_t sul_ind=ue->supplementaryUplink.supplementaryUplink; // this value will be 0 or 1 depending on higher layer parameter ServCellAdd-SUL. FIXME!!! - // 7 BANDWIDTH_PART_IND - // number of UL BWPs configured by higher layers - uint8_t n_UL_BWP_RRC=1; // initialized to 1 but it has to be initialized by higher layers FIXME!!! - n_UL_BWP_RRC = ((n_UL_BWP_RRC > 3)?n_UL_BWP_RRC:(n_UL_BWP_RRC+1)); - // number of DL BWPs configured by higher layers - uint8_t n_DL_BWP_RRC=1; // initialized to 1 but it has to be initialized by higher layers FIXME!!! - n_DL_BWP_RRC = ((n_DL_BWP_RRC > 3)?n_DL_BWP_RRC:(n_DL_BWP_RRC+1)); - // 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL - // if format0_0, only resource allocation type 1 is allowed - // if format0_1, then resource allocation type 0 can be configured and N_RBG is defined in TS 38.214 subclause 6.1.2.2.1 - // for PUSCH hopping with resource allocation type 1 - // n_UL_hopping = 1 if the higher layer parameter frequencyHoppingOffsetLists contains two offset values - // n_UL_hopping = 2 if the higher layer parameter frequencyHoppingOffsetLists contains four offset values - uint8_t n_UL_hopping=pusch_config.n_frequencyHoppingOffsetLists; - - if (n_UL_hopping == 2) { - n_UL_hopping = 1; - } else if (n_UL_hopping == 4) { - n_UL_hopping = 2; - } else { - n_UL_hopping = 0; - } - - ul_resourceAllocation_t ul_resource_allocation_type = pusch_config.ul_resourceAllocation; - uint8_t ul_res_alloc_type_0 = 0; - uint8_t ul_res_alloc_type_1 = 0; - - if (ul_resource_allocation_type == ul_resourceAllocationType0) ul_res_alloc_type_0 = 1; - - if (ul_resource_allocation_type == ul_resourceAllocationType1) ul_res_alloc_type_1 = 1; - - if (ul_resource_allocation_type == ul_dynamicSwitch) { - ul_res_alloc_type_0 = 1; - ul_res_alloc_type_1 = 1; - } - - uint8_t n_bits_freq_dom_res_assign_ul=0,n_ul_RGB_tmp; - - if (ul_res_alloc_type_0 == 1) { // implementation of Table 6.1.2.2.1-1 TC 38.214 subclause 6.1.2.2.1 - // config1: PUSCH-Config IE contains rbg-Size ENUMERATED {config1 config2} - ul_rgb_Size_t config = pusch_config.ul_rgbSize; - uint8_t nominal_RBG_P = (config==ul_rgb_config1?2:4); - - if (n_RB_ULBWP > 36) nominal_RBG_P = (config==ul_rgb_config1?4:8); - - if (n_RB_ULBWP > 72) nominal_RBG_P = (config==ul_rgb_config1?8:16); - - if (n_RB_ULBWP > 144) nominal_RBG_P = 16; - - n_bits_freq_dom_res_assign_ul = (uint8_t)ceil((n_RB_ULBWP+(0%nominal_RBG_P))/nominal_RBG_P); //FIXME!!! what is 0??? - n_ul_RGB_tmp = n_bits_freq_dom_res_assign_ul; - } - - if (ul_res_alloc_type_1 == 1) n_bits_freq_dom_res_assign_ul = (uint8_t)(ceil(log2(n_RB_ULBWP*(n_RB_ULBWP+1)/2)))-n_UL_hopping; - - if ((ul_res_alloc_type_0 == 1) && (ul_res_alloc_type_1 == 1)) - n_bits_freq_dom_res_assign_ul = ((n_bits_freq_dom_res_assign_ul>n_ul_RGB_tmp)?(n_bits_freq_dom_res_assign_ul+1):(n_ul_RGB_tmp+1)); - - // 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL - // if format1_0, only resource allocation type 1 is allowed - // if format1_1, then resource allocation type 0 can be configured and N_RBG is defined in TS 38.214 subclause 5.1.2.2.1 - dl_resourceAllocation_t dl_resource_allocation_type = pdsch_config.dl_resourceAllocation; - uint8_t dl_res_alloc_type_0 = 0; - uint8_t dl_res_alloc_type_1 = 0; - - if (dl_resource_allocation_type == dl_resourceAllocationType0) dl_res_alloc_type_0 = 1; - - if (dl_resource_allocation_type == dl_resourceAllocationType1) dl_res_alloc_type_1 = 1; - - if (dl_resource_allocation_type == dl_dynamicSwitch) { - dl_res_alloc_type_0 = 1; - dl_res_alloc_type_1 = 1; - } - - uint8_t n_bits_freq_dom_res_assign_dl=0,n_dl_RGB_tmp; - - if (dl_res_alloc_type_0 == 1) { // implementation of Table 5.1.2.2.1-1 TC 38.214 subclause 6.1.2.2.1 - // config1: PDSCH-Config IE contains rbg-Size ENUMERATED {config1, config2} - dl_rgb_Size_t config = pdsch_config.dl_rgbSize; - uint8_t nominal_RBG_P = (config==dl_rgb_config1?2:4); - - if (n_RB_DLBWP > 36) nominal_RBG_P = (config==dl_rgb_config1?4:8); - - if (n_RB_DLBWP > 72) nominal_RBG_P = (config==dl_rgb_config1?8:16); - - if (n_RB_DLBWP > 144) nominal_RBG_P = 16; - - n_bits_freq_dom_res_assign_dl = (uint8_t)ceil((n_RB_DLBWP+(0%nominal_RBG_P))/nominal_RBG_P); //FIXME!!! what is 0??? - n_dl_RGB_tmp = n_bits_freq_dom_res_assign_dl; - } - - if (dl_res_alloc_type_1 == 1) n_bits_freq_dom_res_assign_dl = (uint8_t)(ceil(log2(n_RB_DLBWP*(n_RB_DLBWP+1)/2))); - - if ((dl_res_alloc_type_0 == 1) && (dl_res_alloc_type_1 == 1)) - n_bits_freq_dom_res_assign_dl = ((n_bits_freq_dom_res_assign_dl>n_dl_RGB_tmp)?(n_bits_freq_dom_res_assign_dl+1):(n_dl_RGB_tmp+1)); - - // 12 TIME_DOM_RESOURCE_ASSIGNMENT - uint8_t pusch_alloc_list = pusch_config.n_push_alloc_list; - uint8_t pdsch_alloc_list = pdsch_config.n_pdsh_alloc_list; - // 14 PRB_BUNDLING_SIZE_IND:0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214] - static_bundleSize_t static_prb_BundlingType = pdsch_config.prbBundleType.staticBundling; - bundleSizeSet1_t dynamic_prb_BundlingType1 = pdsch_config.prbBundleType.dynamicBundlig.bundleSizeSet1; - bundleSizeSet2_t dynamic_prb_BundlingType2 = pdsch_config.prbBundleType.dynamicBundlig.bundleSizeSet2; - uint8_t prb_BundlingType_size=0; - - if ((static_prb_BundlingType==st_n4)||(static_prb_BundlingType==st_wideband)) prb_BundlingType_size=0; - - if ((dynamic_prb_BundlingType1==dy_1_n4)||(dynamic_prb_BundlingType1==dy_1_wideband)||(dynamic_prb_BundlingType1==dy_1_n2_wideband)||(dynamic_prb_BundlingType1==dy_1_n4_wideband)|| - (dynamic_prb_BundlingType2==dy_2_n4)||(dynamic_prb_BundlingType2==dy_2_wideband)) prb_BundlingType_size=1; - - // 15 RATE_MATCHING_IND FIXME!!! - // according to TS 38.212: Rate matching indicator – 0, 1, or 2 bits according to higher layer parameter rateMatchPattern - uint8_t rateMatching_bits = pdsch_config.n_rateMatchPatterns; - // 16 ZP_CSI_RS_TRIGGER FIXME!!! - // 0, 1, or 2 bits as defined in Subclause 5.1.4.2 of [6, TS 38.214]. - // is the number of ZP CSI-RS resource sets in the higher layer parameter zp-CSI-RS-Resource - uint8_t n_zp_bits = pdsch_config.n_zp_CSI_RS_ResourceId; - // 17 FREQ_HOPPING_FLAG - // freqHopping is defined by higher layer parameter frequencyHopping from IE PUSCH-Config. Values are ENUMERATED{mode1, mode2} - frequencyHopping_t f_hopping = pusch_config.frequencyHopping; - uint8_t freqHopping = 0; - - if ((f_hopping==f_hop_mode1)||(f_hopping==f_hop_mode2)) freqHopping = 1; - - // 28 DAI - pdsch_HARQ_ACK_Codebook_t pdsch_HARQ_ACK_Codebook = pdsch_config.pdsch_HARQ_ACK_Codebook; - uint8_t n_dai = 0; - uint8_t n_serving_cell_dl = 1; // this is hardcoded to 1 as we need to get this value from RRC higher layers parameters. FIXME!!! - - if ((pdsch_HARQ_ACK_Codebook == dynamic) && (n_serving_cell_dl == 1)) n_dai = 2; - - if ((pdsch_HARQ_ACK_Codebook == dynamic) && (n_serving_cell_dl > 1)) n_dai = 4; - - // 29 FIRST_DAI - uint8_t codebook_HARQ_ACK = 0; // We need to get this value to calculate number of bits of fields 1st DAI and 2nd DAI. - - if (pdsch_HARQ_ACK_Codebook == semiStatic) codebook_HARQ_ACK = 1; - - if (pdsch_HARQ_ACK_Codebook == dynamic) codebook_HARQ_ACK = 2; - - // 30 SECOND_DAI - uint8_t n_HARQ_ACK_sub_codebooks = 0; // We need to get this value to calculate number of bits of fields 1st DAI and 2nd DAI. FIXME!!! - // 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND - uint8_t pdsch_harq_t_ind = (uint8_t)ceil(log2(pucch_config_dedicated.dl_DataToUL_ACK[0])); - // 36 SRS_RESOURCE_IND - // n_SRS is the number of configured SRS resources in the SRS resource set associated with the higher layer parameter usage of value 'codeBook' or 'nonCodeBook' - // from SRS_ResourceSet_t type we should get the information of the usage parameter (with possible values beamManagement, codebook, nonCodebook, antennaSwitching) - // at frame_parms->srs_nr->p_SRS_ResourceSetList[]->usage - uint8_t n_SRS = ue->srs.number_srs_Resource_Set; - // 37 PRECOD_NBR_LAYERS - // 38 ANTENNA_PORTS - txConfig_t txConfig = pusch_config.txConfig; - transformPrecoder_t transformPrecoder = pusch_config.transformPrecoder; - codebookSubset_t codebookSubset = pusch_config.codebookSubset; - uint8_t maxRank = pusch_config.maxRank; - uint8_t num_antenna_ports = 1; // this is hardcoded. We need to get the real value FIXME!!! - uint8_t precond_nbr_layers_bits = 0; - uint8_t antenna_ports_bits_ul = 0; - - // searching number of bits at tables 7.3.1.1.2-2/3/4/5 from TS 38.212 subclause 7.3.1.1.2 - if (txConfig == txConfig_codebook) { - if (num_antenna_ports == 4) { - if ((transformPrecoder == transformPrecoder_disabled) && ((maxRank == 2)||(maxRank == 3)||(maxRank == 4))) { // Table 7.3.1.1.2-2 - if (codebookSubset == codebookSubset_fullyAndPartialAndNonCoherent) precond_nbr_layers_bits=6; - - if (codebookSubset == codebookSubset_partialAndNonCoherent) precond_nbr_layers_bits=5; - - if (codebookSubset == codebookSubset_nonCoherent) precond_nbr_layers_bits=4; - } - - if (((transformPrecoder == transformPrecoder_enabled)||(transformPrecoder == transformPrecoder_disabled)) && (maxRank == 1)) { // Table 7.3.1.1.2-3 - if (codebookSubset == codebookSubset_fullyAndPartialAndNonCoherent) precond_nbr_layers_bits=5; - - if (codebookSubset == codebookSubset_partialAndNonCoherent) precond_nbr_layers_bits=4; - - if (codebookSubset == codebookSubset_nonCoherent) precond_nbr_layers_bits=2; - } - } - - if (num_antenna_ports == 2) { - if ((transformPrecoder == transformPrecoder_disabled) && (maxRank == 2)) { // Table 7.3.1.1.2-4 - if (codebookSubset == codebookSubset_fullyAndPartialAndNonCoherent) precond_nbr_layers_bits=4; - - if (codebookSubset == codebookSubset_nonCoherent) precond_nbr_layers_bits=2; - } - - if (((transformPrecoder == transformPrecoder_enabled)||(transformPrecoder == transformPrecoder_disabled)) && (maxRank == 1)) { // Table 7.3.1.1.2-5 - if (codebookSubset == codebookSubset_fullyAndPartialAndNonCoherent) precond_nbr_layers_bits=3; - - if (codebookSubset == codebookSubset_nonCoherent) precond_nbr_layers_bits=1; - } - } - } - - if (txConfig == txConfig_nonCodebook) { - } - - // searching number of bits at tables 7.3.1.1.2-6/7/8/9/10/11/12/13/14/15/16/17/18/19 - if((dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)) { - if ((transformPrecoder == transformPrecoder_enabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len1)) antenna_ports_bits_ul = 2; - - if ((transformPrecoder == transformPrecoder_enabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len2)) antenna_ports_bits_ul = 4; - - if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len1)) antenna_ports_bits_ul = 3; - - if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len2)) antenna_ports_bits_ul = 4; - } - - if((dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type2)) { - if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len1)) antenna_ports_bits_ul = 4; - - if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len2)) antenna_ports_bits_ul = 5; - } - - // for format 1_1 number of bits as defined by Tables 7.3.1.2.2-1/2/3/4 - uint8_t antenna_ports_bits_dl = 0; - - if((dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type1) && (dmrs_DownlinkConfig.pdsch_maxLength == pdsch_len1)) antenna_ports_bits_dl = 4; // Table 7.3.1.2.2-1 - - if((dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type1) && (dmrs_DownlinkConfig.pdsch_maxLength == pdsch_len2)) antenna_ports_bits_dl = 5; // Table 7.3.1.2.2-2 - - if((dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type2) && (dmrs_DownlinkConfig.pdsch_maxLength == pdsch_len1)) antenna_ports_bits_dl = 5; // Table 7.3.1.2.2-3 - - if((dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type2) && (dmrs_DownlinkConfig.pdsch_maxLength == pdsch_len2)) antenna_ports_bits_dl = 6; // Table 7.3.1.2.2-4 - - // 39 TCI - uint8_t tci_bits=0; - - if (pdcch_vars2->coreset[p].tciPresentInDCI == tciPresentInDCI_enabled) tci_bits=3; - - // 42 CSI_REQUEST - // reportTriggerSize is defined in the CSI-MeasConfig IE (TS 38.331). - // Size of CSI request field in DCI (bits). Corresponds to L1 parameter 'ReportTriggerSize' (see 38.214, section 5.2) - uint8_t reportTriggerSize = csi_MeasConfig.reportTriggerSize; // value from 0..6 - // 43 CBGTI - // for format 0_1 - uint8_t maxCodeBlockGroupsPerTransportBlock = 0; - - if (PUSCH_ServingCellConfig.maxCodeBlockGroupsPerTransportBlock != 0) - maxCodeBlockGroupsPerTransportBlock = (uint8_t)PUSCH_ServingCellConfig.maxCodeBlockGroupsPerTransportBlock; - - // for format 1_1, as defined in Subclause 5.1.7 of [6, TS38.214] - uint8_t maxCodeBlockGroupsPerTransportBlock_dl = 0; - - if (PDSCH_ServingCellConfig.maxCodeBlockGroupsPerTransportBlock_dl != 0) - maxCodeBlockGroupsPerTransportBlock_dl = pdsch_config.maxNrofCodeWordsScheduledByDCI; // FIXME!!! - - // 44 CBGFI - uint8_t cbgfi_bit = PDSCH_ServingCellConfig.codeBlockGroupFlushIndicator; - // 45 PTRS_DMRS - // 0 bit if PTRS-UplinkConfig is not configured and transformPrecoder=disabled, or if transformPrecoder=enabled, or if maxRank=1 - // 2 bits otherwise - uint8_t ptrs_dmrs_bits=0; //FIXME!!! - // 46 BETA_OFFSET_IND - // at IE PUSCH-Config, beta_offset indicator – 0 if the higher layer parameter betaOffsets = semiStatic; otherwise 2 bits - // uci-OnPUSCH - // Selection between and configuration of dynamic and semi-static beta-offset. If the field is absent or released, the UE applies the value 'semiStatic' and the BetaOffsets - uint8_t betaOffsets = 0; - - if (pusch_config.uci_onPusch.betaOffset_type == betaOffset_semiStatic); - - if (pusch_config.uci_onPusch.betaOffset_type == betaOffset_dynamic) betaOffsets = 2; - - // 47 DMRS_SEQ_INI - uint8_t dmrs_seq_ini_bits_ul = 0; - uint8_t dmrs_seq_ini_bits_dl = 0; - - //1 bit if both scramblingID0 and scramblingID1 are configured in DMRS-UplinkConfig - if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.scramblingID0 != 0) && (dmrs_UplinkConfig.scramblingID1 != 0)) dmrs_seq_ini_bits_ul = 1; - - //1 bit if both scramblingID0 and scramblingID1 are configured in DMRS-DownlinkConfig - if ((dmrs_DownlinkConfig.scramblingID0 != 0) && (dmrs_DownlinkConfig.scramblingID0 != 0)) dmrs_seq_ini_bits_dl = 1; - - /* - * For format 2_2 - * - * This format supports power control commands for semi-persistent scheduling. - * As we can already support power control commands dynamically with formats 0_0/0_1 (TPC PUSCH) and 1_0/1_1 (TPC PUCCH) - * - * This format will be implemented in the future FIXME!!! - * - */ - // 5 BLOCK_NUMBER: The parameter tpc-PUSCH or tpc-PUCCH provided by higher layers determines the index to the block number for an UL of a cell - // The following fields are defined for each block: Closed loop indicator and TPC command - // 6 CLOSE_LOOP_IND - // 41 TPC_CMD - uint8_t tpc_cmd_bit_2_2 = 2; - /* - * For format 2_3 - * - * This format is used for power control of uplink sounding reference signals for devices which have not coupled SRS power control to the PUSCH power control - * either because independent control is desirable or because the device is configured without PUCCH and PUSCH - * - * This format will be implemented in the future FIXME!!! - * - */ - // 40 SRS_REQUEST - // 41 TPC_CMD - uint8_t tpc_cmd_bit_2_3 = 0; - uint8_t dci_field_size_table [NBR_NR_DCI_FIELDS][NBR_NR_FORMATS] = { // This table contains the number of bits for each field (row) contained in each dci format (column). - // The values of the variables indicate field sizes in number of bits - //Format0_0 Format0_1 Format1_0 Format1_1 Formats2_0/1/2/3 - { - 1, 1, (((crc_scrambled == _p_rnti) || (crc_scrambled == _si_rnti) || (crc_scrambled == _ra_rnti)) ? 0:1), - 1, 0,0,0,0 - }, // 0 IDENTIFIER_DCI_FORMATS: - { - 0, ((crossCarrierSchedulingConfig_ind == 0) ? 0:3), - 0, ((crossCarrierSchedulingConfig_ind == 0) ? 0:3), - 0,0,0,0 - }, // 1 CARRIER_IND: 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213] - {0, (sul_ind == 0)?0:1, 0, 0, 0,0,0,0}, // 2 SUL_IND_0_1: - {0, 0, 0, 0, 1,0,0,0}, // 3 SLOT_FORMAT_IND: size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213] - {0, 0, 0, 0, 0,1,0,0}, // 4 PRE_EMPTION_IND: size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits - {0, 0, 0, 0, 0,0,0,0}, // 5 BLOCK_NUMBER: starting position of a block is determined by the parameter startingBitOfFormat2_3 - {0, 0, 0, 0, 0,0,1,0}, // 6 CLOSE_LOOP_IND - { - 0, (uint8_t)ceil(log2(n_UL_BWP_RRC)), - 0, (uint8_t)ceil(log2(n_DL_BWP_RRC)), - 0,0,0,0 - }, // 7 BANDWIDTH_PART_IND: - { - 0, 0, ((crc_scrambled == _p_rnti) ? 2:0), - 0, 0,0,0,0 - }, // 8 SHORT_MESSAGE_IND 2 bits if crc scrambled with P-RNTI - { - 0, 0, ((crc_scrambled == _p_rnti) ? 8:0), - 0, 0,0,0,0 - }, // 9 SHORT_MESSAGES 8 bit8 if crc scrambled with P-RNTI - { - (uint8_t)(ceil(log2(n_RB_ULBWP*(n_RB_ULBWP+1)/2)))-n_UL_hopping, - n_bits_freq_dom_res_assign_ul, - 0, 0, 0,0,0,0 - }, // 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered - // (NOTE 1) If DCI format 0_0 is monitored in common search space - // and if the number of information bits in the DCI format 0_0 prior to padding - // is larger than the payload size of the DCI format 1_0 monitored in common search space - // the bitwidth of the frequency domain resource allocation field in the DCI format 0_0 - // is reduced such that the size of DCI format 0_0 equals to the size of the DCI format 1_0 - { - 0, 0, (uint8_t)ceil(log2(n_RB_DLBWP*(n_RB_DLBWP+1)/2)), - n_bits_freq_dom_res_assign_dl, - 0,0,0,0 - }, // 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - { - 4, (uint8_t)log2(pusch_alloc_list), - 4, (uint8_t)log2(pdsch_alloc_list), - 0,0,0,0 - }, // 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - // where I the number of entries in the higher layer parameter pusch-AllocationList - { - 0, 0, 1, (((dl_res_alloc_type_0==1) &&(dl_res_alloc_type_1==0))?0:1), - 0,0,0,0 - }, // 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - {0, 0, 0, prb_BundlingType_size, 0,0,0,0}, // 14 PRB_BUNDLING_SIZE_IND:0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214] - {0, 0, 0, rateMatching_bits, 0,0,0,0}, // 15 RATE_MATCHING_IND: 0, 1, or 2 bits according to higher layer parameter rate-match-PDSCH-resource-set - {0, 0, 0, n_zp_bits, 0,0,0,0}, // 16 ZP_CSI_RS_TRIGGER: - { - 1, (((ul_res_alloc_type_0==1) &&(ul_res_alloc_type_1==0))||(freqHopping == 0))?0:1, - 0, 0, 0,0,0,0 - }, // 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 - {0, 0, 0, 5, 0,0,0,0}, // 18 TB1_MCS: - {0, 0, 0, 1, 0,0,0,0}, // 19 TB1_NDI: - {0, 0, 0, 2, 0,0,0,0}, // 20 TB1_RV: - {0, 0, 0, 5, 0,0,0,0}, // 21 TB2_MCS: - {0, 0, 0, 1, 0,0,0,0}, // 22 TB2_NDI: - {0, 0, 0, 2, 0,0,0,0}, // 23 TB2_RV: - {5, 5, 5, 0, 0,0,0,0}, // 24 MCS: - {1, 1, (crc_scrambled == _c_rnti)?1:0,0, 0,0,0,0}, // 25 NDI: - { - 2, 2, (((crc_scrambled == _c_rnti) || (crc_scrambled == _si_rnti)) ? 2:0), - 0, 0,0,0,0 - }, // 26 RV: - {4, 4, (crc_scrambled == _c_rnti)?4:0,4, 0,0,0,0}, // 27 HARQ_PROCESS_NUMBER: - {0, 0, (crc_scrambled == _c_rnti)?2:0,n_dai, 0,0,0,0}, // 28 DAI: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - // 2 if one serving cell is configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 bits are the counter DAI - // 0 otherwise - {0, codebook_HARQ_ACK, 0, 0, 0,0,0,0}, // 29 FIRST_DAI: (1 or 2 bits) 1 bit for semi-static HARQ-ACK // 2 bits for dynamic HARQ-ACK codebook with single HARQ-ACK codebook - { - 0, (((codebook_HARQ_ACK == 2) &&(n_HARQ_ACK_sub_codebooks==2))?2:0), - 0, 0, 0,0,0,0 - }, // 30 SECOND_DAI: (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks // 0 bits otherwise - { - 0, 0, (((crc_scrambled == _p_rnti) || (crc_scrambled == _ra_rnti)) ? 2:0), - 0, 0,0,0,0 - }, // 31 TB_SCALING - {2, 2, 0, 0, 0,0,0,0}, // 32 TPC_PUSCH: - {0, 0, (crc_scrambled == _c_rnti)?2:0,2, 0,0,0,0}, // 33 TPC_PUCCH: - {0, 0, (crc_scrambled == _c_rnti)?3:0,3, 0,0,0,0}, // 34 PUCCH_RESOURCE_IND: - {0, 0, (crc_scrambled == _c_rnti)?3:0,pdsch_harq_t_ind, 0,0,0,0}, // 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: - {0, (uint8_t)log2(n_SRS), 0, 0, 0,0,0,0}, // 36 SRS_RESOURCE_IND: - {0, precond_nbr_layers_bits, 0, 0, 0,0,0,0}, // 37 PRECOD_NBR_LAYERS: - {0, antenna_ports_bits_ul, 0, antenna_ports_bits_dl, 0,0,0,0}, // 38 ANTENNA_PORTS: - {0, 0, 0, tci_bits, 0,0,0,0}, // 39 TCI: 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits - {0, (sul_ind == 0)?2:3, 0, (sul_ind == 0)?2:3, 0,0,0,2}, // 40 SRS_REQUEST: - { - 0, 0, 0, 0, 0,0,tpc_cmd_bit_2_2, - tpc_cmd_bit_2_3 - }, - // 41 TPC_CMD: - {0, reportTriggerSize, 0, 0, 0,0,0,0}, // 42 CSI_REQUEST: - { - 0, maxCodeBlockGroupsPerTransportBlock, - 0, maxCodeBlockGroupsPerTransportBlock_dl, - 0,0,0,0 - }, // 43 CBGTI: 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH - {0, 0, 0, cbgfi_bit, 0,0,0,0}, // 44 CBGFI: 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator - {0, ptrs_dmrs_bits, 0, 0, 0,0,0,0}, // 45 PTRS_DMRS: - {0, betaOffsets, 0, 0, 0,0,0,0}, // 46 BETA_OFFSET_IND: - {0, dmrs_seq_ini_bits_ul, 0, dmrs_seq_ini_bits_dl, 0,0,0,0}, // 47 DMRS_SEQ_INI: 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding - // is larger than the number of bits for DCI format 0_0 before padding; 0 bit otherwise - {0, 1, 0, 0, 0,0,0,0}, // 48 UL_SCH_IND: value of "1" indicates UL-SCH shall be transmitted on the PUSCH and a value of "0" indicates UL-SCH shall not be transmitted on the PUSCH - {0, 0, 0, 0, 0,0,0,0}, // 49 PADDING_NR_DCI: - // (NOTE 2) If DCI format 0_0 is monitored in common search space - // and if the number of information bits in the DCI format 0_0 prior to padding - // is less than the payload size of the DCI format 1_0 monitored in common search space - // zeros shall be appended to the DCI format 0_0 - // until the payload size equals that of the DCI format 1_0 - {(sul_ind == 0)?0:1, 0, 0, 0, 0,0,0,0}, // 50 SUL_IND_0_0: - {0, 0, 0, 0, 0,0,0,0}, // 51 RA_PREAMBLE_INDEX (random access procedure initiated by a PDCCH order not implemented, FIXME!!!) - {0, 0, 0, 0, 0,0,0,0}, // 52 SUL_IND_1_0 (random access procedure initiated by a PDCCH order not implemented, FIXME!!!) - {0, 0, 0, 0, 0,0,0,0}, // 53 SS_PBCH_INDEX (random access procedure initiated by a PDCCH order not implemented, FIXME!!!) - {0, 0, 0, 0, 0,0,0,0}, // 54 PRACH_MASK_INDEX (random access procedure initiated by a PDCCH order not implemented, FIXME!!!) - { - 0, 0, ((crc_scrambled == _p_rnti)?6:(((crc_scrambled == _si_rnti) || (crc_scrambled == _ra_rnti))?16:0)), - 0, 0,0,0,0 - } // 55 RESERVED_NR_DCI - }; - // NOTE 1: adjustments in freq_dom_resource_assignment_UL to be done if necessary - // NOTE 2: adjustments in padding to be done if necessary - uint8_t dci_size [8] = {0,0,0,0,0,0,0,0}; // will contain size for each format - - for (int i=0 ; i i=%d, j=%d\n", i, j); - //#endif - for (int j=0; j position in table is 2) - dci_fields_sizes[j][i] = dci_field_size_table[j][i]; // dci_fields_sizes[j] contains the sizes of each field (j) for a determined format i - //} - } - -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) dci_size[%d]=%d for n_RB_ULBWP=%d\n", - i,dci_size[i],n_RB_ULBWP); -#endif - } - -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) dci_fields_sizes[][] = { \n"); - - for (int j=0; j dci_size[2])) { - dci_field_size_table[SUL_IND_0_0][0] = 0; - dci_size[0]=dci_size[0]-1; - } - // if ((format == format0_0) || (format == format1_0)) { - // According to Section 7.3.1.1.1 in TS 38.212 - // If DCI format 0_0 is monitored in common search space and if the number of information bits in the DCI format 0_0 prior to padding - // is less than the payload size of the DCI format 1_0 monitored in common search space for scheduling the same serving cell, - // zeros shall be appended to the DCI format 0_0 until the payload size equals that of the DCI format 1_0. - if (dci_size[0] < dci_size[2]) { // '0' corresponding to index for format0_0 and '2' corresponding to index of format1_0 - //if (format == format0_0) { - dci_fields_sizes[PADDING_NR_DCI][0] = dci_size[2] - dci_size[0]; - dci_size[0] = dci_size[2]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) new dci_size[format0_0]=%d\n",dci_size[0]); -#endif - //} - } - // If DCI format 0_0 is monitored in common search space and if the number of information bits in the DCI format 0_0 prior to padding - // is larger than the payload size of the DCI format 1_0 monitored in common search space for scheduling the same serving cell, - // the bitwidth of the frequency domain resource allocation field in the DCI format 0_0 is reduced - // such that the size of DCI format 0_0 equals to the size of the DCI format 1_0.. - if (dci_size[0] > dci_size[2]) { - //if (format == format0_0) { - dci_fields_sizes[FREQ_DOM_RESOURCE_ASSIGNMENT_UL][0] -= (dci_size[0] - dci_size[2]); - dci_size[0] = dci_size[2]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) new dci_size[format0_0]=%d\n",dci_size[0]); -#endif - //} - } - /* - * TS 38.212 subclause 7.3.1.1.2 - * For a UE configured with SUL in a cell: - * if PUSCH is configured to be transmitted on both the SUL and the non-SUL of the cell and - * if the number of information bits in format 0_1 for the SUL - * is not equal to the number of information bits in format 0_1 for the non-SUL, - * zeros shall be appended to smaller format 0_1 until the payload size equals that of the larger format 0_1 - * - * Not implemented. FIXME!!! - * - */ - // } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) dci_fields_sizes[][] = { \n"); - for (int j=0; j frame_parms, nr_tti_rx); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> searSpaceType=%d\n",do_common); + LOG_DD("searSpaceType=%d\n",do_common); + LOG_DD("%s_dci_format=%d\n",do_common?"uss":"css",css_dci_format); - if (do_common==0) { - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> css_dci_format=%d\n",css_dci_format); - } else { - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> uss_dci_format=%d\n",uss_dci_format); - } - -#endif // A set of PDCCH candidates for a UE to monitor is defined in terms of PDCCH search spaces if (do_common==0) { // COMMON SearchSpaceType assigned to current SearchSpace/CORESET @@ -2737,18 +1676,14 @@ uint8_t nr_dci_decoding_procedure(int s, // for format0_0 and format1_0, first we calculate dci pdu size format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,0); format_0_0_1_0_size_bytes = (format_0_0_1_0_size_bits%8 == 0) ? (uint8_t)floor(format_0_0_1_0_size_bits/8) : (uint8_t)(floor(format_0_0_1_0_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n", + LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n", css_dci_format,format_0_0_1_0_size_bits,format_0_0_1_0_size_bytes); -#endif for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { // We fix aggregationLevel to 3 for testing=> nbr of CCE=8 //for (int aggregationLevel = 2; aggregationLevel<5 ; aggregationLevel++) { // for aggregation level aggregationLevel. The number of candidates (for L2= 2^aggregationLevel) will be calculated in function nr_dci_decoding_procedure0 -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1< current_thread_id[nr_tti_rx], frame_parms, crc_scrambled_values, aggregationLevel, @@ -2776,16 +1711,12 @@ uint8_t nr_dci_decoding_procedure(int s, // for format2_0, first we calculate dci pdu size format_2_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_sfi_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,4); format_2_0_size_bytes = (format_2_0_size_bits%8 == 0) ? (uint8_t)floor(format_2_0_size_bits/8) : (uint8_t)(floor(format_2_0_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_0_size_bits=%d, format2_0_size_bytes=%d\n", + LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_0_size_bits=%d, format2_0_size_bytes=%d\n", css_dci_format,format_2_0_size_bits,format_2_0_size_bytes); -#endif for (int aggregationLevelSFI = 0; aggregationLevelSFI<5 ; aggregationLevelSFI++) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<