Merge branch 'integration_2024_w35' into 'develop'
Integration: `2024.w35` Closes #825 See merge request oai/openairinterface5g!2943 * !2181 ULSCH power computation * !2915 benchmark for rotate_cpx_vector * !2936 Avoid complete rebuild on cmake run with git info change * !2855 NR UE replace phy_config_request_sent * !2937 small fixes for rfsim * !2925 CI: Increase tested throughput in SA 2x2 pipeline * !2934 Run optimized parity check in ldpc encoder only on supported Zc values * !2912 changes for multi-RU support in fhi72 * !2928 Distribution check: check for F40, remove old U/RHEL releases * !2913 NR gNB cleanup * !2927 Update Aerial docs to reference current version * !2940 remove double define with nr_common.h
This commit is contained in:
+15
-17
@@ -84,7 +84,6 @@ set (OPENAIR2_DIR ${OPENAIR_DIR}/openair2)
|
||||
set (OPENAIR3_DIR ${OPENAIR_DIR}/openair3)
|
||||
set (OPENAIR3_DIR ${OPENAIR_DIR}/openair3)
|
||||
set (OPENAIR_CMAKE ${OPENAIR_DIR}/cmake_targets)
|
||||
set (OPENAIR_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY})
|
||||
|
||||
project (OpenAirInterface)
|
||||
|
||||
@@ -254,12 +253,6 @@ if(GIT_FOUND)
|
||||
)
|
||||
endif()
|
||||
|
||||
# Below is a hard-coded info
|
||||
set (FIRMWARE_VERSION "No svn information")
|
||||
add_definitions("-DFIRMWARE_VERSION=\"${FIRMWARE_VERSION}\"")
|
||||
add_definitions("-DPACKAGE_VERSION=\"Branch: ${GIT_BRANCH} Abrev. Hash: ${GIT_COMMIT_HASH} Date: ${GIT_COMMIT_DATE}\"")
|
||||
add_definitions("-DPACKAGE_BUGREPORT=\"openair4g-devel@lists.eurecom.fr\"")
|
||||
|
||||
# Debug related options
|
||||
#########################################
|
||||
add_boolean_option(DEBUG_ASN1 False "Enable ASN1 debug logs" OFF)
|
||||
@@ -544,16 +537,8 @@ add_boolean_option(NAS_UE True "NAS UE INSTANCE (<> NAS_MME)"
|
||||
add_boolean_option(RRC_DEFAULT_RAB_IS_AM True "set the LTE RLC mode to AM for the default bearer, otherwise it is UM." ON)
|
||||
|
||||
# add the binary tree to the search path for include files
|
||||
#######################################################
|
||||
# We will find ConfigOAI.h after generation in target directory
|
||||
include_directories("${OPENAIR_BIN_DIR}")
|
||||
# add directories to find all include files
|
||||
# the internal rule is to use generic names such as defs.h
|
||||
# but to make it uniq name as adding the relative path in the include directtive
|
||||
# example: #include "RRC/LTE/rrc_defs.h"
|
||||
#find_path (include_dirs_all *.h ${OPENAIR_DIR})
|
||||
#find_path (include_dirs_all *.h PATHS /usr/include NO_CMAKE_PATH)
|
||||
#include_directories("${include_dirs_all}")
|
||||
# We will find common/oai_version.h after generation in target directory
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# Legacy exact order
|
||||
|
||||
@@ -2367,6 +2352,19 @@ if(ENABLE_TESTS)
|
||||
add_library(GTest::gtest ALIAS gtest)
|
||||
add_library(GTest::gtest_main ALIAS gtest_main)
|
||||
endif()
|
||||
|
||||
find_package(benchmark)
|
||||
if (NOT benchmark_FOUND)
|
||||
message(STATUS "benchmark package not found, will download benchmark automatically. To prevent that install google benchmark on your system (libbenchmark-dev)")
|
||||
include(FetchContent)
|
||||
set(BENCHMARK_ENABLE_TESTING OFF)
|
||||
FetchContent_Declare(
|
||||
benchmark
|
||||
GIT_REPOSITORY https://github.com/google/benchmark.git
|
||||
GIT_TAG v1.9.0
|
||||
)
|
||||
FetchContent_MakeAvailable(benchmark)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_subdirectory(common)
|
||||
|
||||
@@ -212,7 +212,7 @@ RUs = (
|
||||
att_rx = 0;
|
||||
bands = [77];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 72;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
|
||||
@@ -106,12 +106,12 @@
|
||||
|
||||
<testCase id="071100">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/500Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 500M -t 30 -R -O 10 -l 9000</iperf_args>
|
||||
<desc>iperf (DL/600Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 600M -t 30 -R -O 10 -l 9000</iperf_args>
|
||||
<svr_id>matix-cn5g</svr_id>
|
||||
<id>up2</id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
|
||||
<iperf_bitrate_threshold>70</iperf_bitrate_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="071101">
|
||||
|
||||
@@ -116,8 +116,8 @@
|
||||
|
||||
<testCase id="071001">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/130Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 130M -t 30</iperf_args>
|
||||
<desc>iperf (UL/180Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 180M -t 30</iperf_args>
|
||||
<svr_id>matix-cn5g</svr_id>
|
||||
<id>up2</id>
|
||||
<iperf_packetloss_threshold>10</iperf_packetloss_threshold>
|
||||
|
||||
@@ -6,7 +6,6 @@ cuBB_Path="${cuBB_SDK:-/opt/nvidia/cuBB}"
|
||||
cd "$cuBB_Path" || exit 1
|
||||
# Add gdrcopy to LD_LIBRARY_PATH
|
||||
export LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/opt/mellanox/dpdk/lib/x86_64-linux-gnu:/opt/mellanox/doca/lib/x86_64-linux-gnu:/opt/nvidia/cuBB/cuPHY-CP/external/gdrcopy/build/x86_64/
|
||||
export LD_LIBRARY_PATH=$LD_LIBRART_PATH:"$cuBB_Path/gpu-dpdk/build/install/lib/x86_64-linux-gnu:$cuBB_Path/build/cuPHY-CP/cuphydriver/src"
|
||||
|
||||
# Restart MPS
|
||||
# Export variables
|
||||
|
||||
@@ -79,17 +79,19 @@
|
||||
<main_exec>ldpctest</main_exec>
|
||||
<main_exec_args>-l3872 -s10 -n100
|
||||
-l4224 -s10 -n100
|
||||
-l4576 -s10 -n100
|
||||
-l4928 -s10 -n100
|
||||
-l5280 -s10 -n100
|
||||
-l5632 -s10 -n100
|
||||
-l6336 -s10 -n100
|
||||
-l7040 -s10 -n100
|
||||
-l7744 -s10 -n100
|
||||
-l8448 -s10 -n100</main_exec_args>
|
||||
-l4576 -s10 -n100
|
||||
-l4928 -s10 -n100
|
||||
-l5280 -s10 -n100
|
||||
-l5632 -s10 -n100
|
||||
-l6336 -s10 -n100
|
||||
-l7040 -s10 -n100
|
||||
-l7744 -s10 -n100
|
||||
-l8448 -s10 -n100
|
||||
-l561 -s10 -n1
|
||||
-l500 -s10 -n1</main_exec_args>
|
||||
<tags>test1 test2 test3 test4 test5 test6 test7 test8 test9 test10</tags>
|
||||
<search_expr_true>BLER 0.000000</search_expr_true>
|
||||
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
|
||||
<search_expr_false>segmentation fault|assertion|exiting|fatal|differ</search_expr_false>
|
||||
<nruns>3</nruns>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ case "$OS_DISTRO" in
|
||||
fedora) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;;
|
||||
rhel) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake3" ;;
|
||||
rocky) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;;
|
||||
centos) OS_BASEDISTRO="centos"; INSTALLER="yum"; CMAKE="cmake3" ;;
|
||||
centos) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake3" ;; # CentOS Stream
|
||||
debian) OS_BASEDISTRO="debian"; INSTALLER="apt-get"; CMAKE="cmake" ;;
|
||||
ubuntu) OS_BASEDISTRO="debian"; INSTALLER="apt-get"; CMAKE="cmake" ;;
|
||||
esac
|
||||
@@ -104,18 +104,10 @@ check_supported_distribution() {
|
||||
local distribution=$(get_distribution_release)
|
||||
case "$distribution" in
|
||||
"ubuntu24.04") return 0 ;;
|
||||
"ubuntu23.10") return 0 ;;
|
||||
"ubuntu22.04") return 0 ;;
|
||||
"ubuntu21.04") return 0 ;;
|
||||
"ubuntu20.04") return 0 ;;
|
||||
"debian11") return 0 ;;
|
||||
"fedora36") return 0 ;;
|
||||
"fedora37") return 0 ;;
|
||||
"rhel7") return 0 ;;
|
||||
"rhel7.6") return 0 ;;
|
||||
"rhel7.7") return 0 ;;
|
||||
"rhel7.8") return 0 ;;
|
||||
"rhel7.9") return 0 ;;
|
||||
"fedora40") return 0 ;;
|
||||
"rhel8.2") return 0 ;;
|
||||
"rhel8.3") return 0 ;;
|
||||
"rhel8.4") return 0 ;;
|
||||
@@ -129,8 +121,7 @@ check_supported_distribution() {
|
||||
"rhel9.2") return 0 ;;
|
||||
"rhel9.3") return 0 ;;
|
||||
"rhel9.4") return 0 ;;
|
||||
"centos7") return 0 ;;
|
||||
"centos8") return 0 ;;
|
||||
"centos9") return 0 ;; # CentOS stream
|
||||
"rocky8.7") return 0 ;;
|
||||
"rocky8.8") return 0 ;;
|
||||
"rocky8.9") return 0 ;;
|
||||
@@ -388,16 +379,16 @@ install_usrp_uhd_driver() {
|
||||
# On newer kernels, it fails to install
|
||||
$SUDO apt-get -y install uhd-host
|
||||
fi
|
||||
# quick workaround for RHE7.6
|
||||
# quick workaround for below distributions
|
||||
local distribution=$(get_distribution_release)
|
||||
if [ -z $1 ]; then
|
||||
if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "rocky" ]]; then
|
||||
if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "rocky" ]] || [[ "$OS_DISTRO" == "centos" ]]; then
|
||||
$SUDO /usr/local/bin/uhd_images_downloader
|
||||
else
|
||||
$SUDO uhd_images_downloader
|
||||
fi
|
||||
else
|
||||
if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "rocky" ]]; then
|
||||
if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "rocky" ]] || [[ "$OS_DISTRO" == "centos" ]]; then
|
||||
$SUDO /usr/local/bin/uhd_images_downloader -i $1
|
||||
else
|
||||
$SUDO uhd_images_downloader -i $1
|
||||
@@ -537,7 +528,7 @@ check_install_additional_tools (){
|
||||
local optional_packages=""
|
||||
if [[ "$OS_BASEDISTRO" == "debian" ]]; then
|
||||
case "$(get_distribution_release)" in
|
||||
"ubuntu20.04" | "ubuntu21.04" | "ubuntu22.04" | "debian11" )
|
||||
"ubuntu20.04" | "ubuntu22.04" | "debian11" )
|
||||
optional_packages="python3 python3-pip python3-dev python3-scipy python3-matplotlib python3-pyroute2 universal-ctags"
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
add_subdirectory(utils)
|
||||
|
||||
configure_file(oai_version.h.in oai_version.h @ONLY)
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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 OAI_VERSION_H_
|
||||
#define OAI_VERSION_H_
|
||||
|
||||
#define GIT_BRANCH "@GIT_BRANCH@"
|
||||
#define GIT_COMMIT_HASH "@GIT_COMMIT_HASH@"
|
||||
#define GIT_COMMIT_DATE "@GIT_COMMIT_DATE@"
|
||||
|
||||
#define OAI_FIRMWARE_VERSION GIT_COMMIT_HASH
|
||||
#define OAI_PACKAGE_VERSION "Branch: " GIT_BRANCH " Abrev. Hash: " GIT_COMMIT_HASH " Date: " GIT_COMMIT_DATE
|
||||
|
||||
#endif /* OAI_VERSION_H_ */
|
||||
@@ -6,7 +6,7 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf)
|
||||
* Formats the full shared library path, using the `modname` argument and the loader `shlibpath` and `shlibversion`configuration parameters.
|
||||
* loads the shared library, using the dlopen system call
|
||||
* looks for `< modname >_autoinit` symbol, using the `dlsym` system call and possibly call the corresponding function.
|
||||
* looks for `< modname >_checkbuildver` symbol, using the `dlsym` system call and possibly calls the corresponding function. If the return value of this call is `-1`, program execution is stopped. It is the responsibility of the shared library developer to implement or not a `< modname >_checkbuildver` function and to decide if a version mismatch is a fatal condition. The `< modname >_checkbuildver` function must match the `checkverfunc_t` function type. The first argument is the main executable version, as set in the `PACKAGE_VERSION` macro defined in the [oai CMakeLists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/CMakeLists.txt#L218), around line 218. The second argument points to the shared library version which should be set by the `< modname >_checkbuildver` function.
|
||||
* looks for `< modname >_checkbuildver` symbol, using the `dlsym` system call and possibly calls the corresponding function. If the return value of this call is `-1`, program execution is stopped. It is the responsibility of the shared library developer to implement or not a `< modname >_checkbuildver` function and to decide if a version mismatch is a fatal condition. The `< modname >_checkbuildver` function must match the `checkverfunc_t` function type. The first argument is the main executable version, as set in the `OAI_PACKAGE_VERSION` macro defined in the [`common/CMakeLists`](../../../CMakeLists). The second argument points to the shared library version which should be set by the `< modname >_checkbuildver` function.
|
||||
* If the farray pointer is null, looks for `< modname >_getfarray` symbol, calls the corresponding function when the symbol is found. `< modname >_getfarray` takes one argument, a pointer to a `loader_shlibfunc_t` array, and returns the number of items in this array, as defined by the `getfarrayfunc_t` type. The `loader_shlibfunc_t` array returned by the shared library must be fully filled (both `fname` and `fptr` fields).
|
||||
* looks for the `numf` function symbols listed in the `farray[i].fname` arguments and set the corresponding `farray[i].fptr`function pointers
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <dlfcn.h>
|
||||
#include "openair1/PHY/defs_common.h"
|
||||
#include "common/oai_version.h"
|
||||
#define LOAD_MODULE_SHLIB_MAIN
|
||||
|
||||
#include "common/config/config_userapi.h"
|
||||
@@ -45,7 +46,7 @@
|
||||
void loader_init(void) {
|
||||
paramdef_t LoaderParams[] = LOADER_PARAMS_DESC;
|
||||
|
||||
loader_data.mainexec_buildversion = PACKAGE_VERSION;
|
||||
loader_data.mainexec_buildversion = OAI_PACKAGE_VERSION;
|
||||
int ret = config_get(config_get_if(), LoaderParams, sizeofArray(LoaderParams), LOADER_CONFIG_PREFIX);
|
||||
if (ret <0) {
|
||||
printf("[LOADER] configuration couldn't be performed via config module, parameters set to default values\n");
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include <readline/history.h>
|
||||
#include "common/oai_version.h"
|
||||
|
||||
|
||||
#include "telnetsrv_phycmd.h"
|
||||
@@ -938,10 +939,7 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde
|
||||
against main exec version. version mismatch not considered as fatal (interfaces not supposed to change)
|
||||
*/
|
||||
int telnetsrv_checkbuildver(char *mainexec_buildversion, char **shlib_buildversion) {
|
||||
#ifndef PACKAGE_VERSION
|
||||
#define PACKAGE_VERSION "standalone built: " __DATE__ __TIME__
|
||||
#endif
|
||||
*shlib_buildversion = PACKAGE_VERSION;
|
||||
*shlib_buildversion = OAI_PACKAGE_VERSION;
|
||||
|
||||
if (strcmp(mainexec_buildversion, *shlib_buildversion) != 0) {
|
||||
fprintf(stderr,"[TELNETSRV] shared lib version %s, doesn't match main version %s, compatibility should be checked\n",
|
||||
|
||||
@@ -87,6 +87,6 @@ add_custom_target(
|
||||
add_dependencies(websrv websrvfront)
|
||||
# copy frontend files to a websrv subdirectory of where oai copy all built files
|
||||
add_custom_command(TARGET websrvfront
|
||||
POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/frontend/dist/softmodem-ngx ${OPENAIR_BIN_DIR}/../websrv
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/helpfiles ${OPENAIR_BIN_DIR}/../websrv/helpfiles
|
||||
COMMENT "Moving frontend files to:\n ${OPENAIR_BIN_DIR}/../websrv \n " )
|
||||
POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/frontend/dist/softmodem-ngx ${CMAKE_CURRENT_BINARY_DIR}/../websrv
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/helpfiles ${CMAKE_CURRENT_BINARY_DIR}/../websrv/helpfiles
|
||||
COMMENT "Moving frontend files to: ${CMAKE_CURRENT_BINARY_DIR}/../websrv" )
|
||||
|
||||
@@ -50,6 +50,7 @@ The UEs that have been tested and confirmed working with Aerial are the followin
|
||||
|-----------------|-------------------------------|
|
||||
| Sierra Wireless | EM9191 |
|
||||
| Quectel | RM500Q-GL |
|
||||
| Quectel | RM520N-GL |
|
||||
| Apaltec | Tributo 5G-Dongle |
|
||||
| OnePlus | Nord (AC2003) |
|
||||
| Apple iPhone | 14 Pro (MQ0G3RX/A) (iOS 17.3) |
|
||||
@@ -59,9 +60,9 @@ The UEs that have been tested and confirmed working with Aerial are the followin
|
||||
|
||||
The first step is to obtain the NVIDIA Aerial SDK, you'll need to request access [here](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/aerial-sdk).
|
||||
|
||||
After obtaining access to the SDK, you can refer to [this instructions page](https://docs.nvidia.com/aerial/aerial-research-cloud/current/index.html) to setup the L1 components using NVIDIAs' SDK manager, or to [this instructions page](https://developer.nvidia.com/docs/gputelecom/aerial-sdk/aerial-sdk-archive/aerial-sdk-23-2/index.html) in order to setup and install the components manually.
|
||||
After obtaining access to the SDK, you can refer to [this instructions page](https://docs.nvidia.com/aerial/aerial-ran-colab-ota/current/index.html) to setup the L1 components using NVIDIAs' SDK manager, or to [this instructions page](https://docs.nvidia.com/aerial/cuda-accelerated-ran/index.html) in order to setup and install the components manually.
|
||||
|
||||
The currently used Aerial Version is 23-2, which is also the one currently used by the SDK Manager.
|
||||
The currently used Aerial Version is 24-1, which is also the one currently used by the SDK Manager.
|
||||
|
||||
|
||||
### CPU allocation
|
||||
@@ -139,7 +140,7 @@ After=ptp4l.service
|
||||
Restart=always
|
||||
RestartSec=5s
|
||||
Type=simple
|
||||
ExecStart=/usr/sbin/phc2sys -a -r -r -n 24
|
||||
ExecStart=/usr/sbin/phc2sys -a -r -n 24
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -154,7 +155,6 @@ Clone OAI code base in a suitable repository, here we are cloning in `~/openairi
|
||||
```bash
|
||||
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g
|
||||
cd ~/openairinterface5g/
|
||||
git checkout Aerial_Integration
|
||||
```
|
||||
|
||||
## Get nvIPC sources from the L1 container
|
||||
@@ -174,27 +174,44 @@ If it is not running, you may start it and logging into the container by running
|
||||
~$ docker start cuBB
|
||||
cuBB
|
||||
~$ docker exec -it cuBB bash
|
||||
root@c_aerial_aerial:/opt/nvidia/cuBB#
|
||||
aerial@c_aerial_aerial:/opt/nvidia/cuBB#
|
||||
```
|
||||
|
||||
After logging into the container, we need to pack the nvIPC sources and copy them to the host ( the command creates a tar.gz file with the following name format: nvipc_src.yyyy.mm.dd.tar.gz)
|
||||
After logging into the container, we need to pack the nvIPC sources and copy them to the host ( the command creates a tar.gz file with the following name format: nvipc_src.YYYY.MM.DD.tar.gz)
|
||||
```bash
|
||||
~$ docker exec -it cuBB bash
|
||||
root@c_aerial_aerial:/opt/nvidia/cuBB# cd cuPHY-CP/gt_common_libs
|
||||
root@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs#./pack_nvipc.sh
|
||||
nvipc_src.****.**.**/
|
||||
aerial@c_aerial_aerial:/opt/nvidia/cuBB# cd cuPHY-CP/gt_common_libs
|
||||
aerial@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs#./pack_nvipc.sh
|
||||
nvipc_src.YYYY.MM.DD/
|
||||
...
|
||||
---------------------------------------------
|
||||
Pack nvipc source code finished:
|
||||
/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs/nvipc_src.****.**.**.tar.gz
|
||||
root@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs# cp nvipc_src.****.**.**.tar.gz /opt/cuBB/share/
|
||||
root@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs# exit
|
||||
/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs/nvipc_src.YYYY.MM.DD.tar.gz
|
||||
aerial@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs# sudo cp nvipc_src.yyyy.mm.dd.tar.gz /opt/cuBB/share/
|
||||
aerial@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs# exit
|
||||
```
|
||||
|
||||
The file should now be present in the `~/openairinterface5g/ci-scripts/yaml_files/sa_gnb_aerial/` directory, from where it is moved into `~/openairinterface5g`
|
||||
```bash
|
||||
~$ mv ~/openairinterface5g/ci-scripts/yaml_files/sa_gnb_aerial/nvipc_src.****.**.**.tar.gz ~/openairinterface5g/
|
||||
~$ mv ~/openairinterface5g/ci-scripts/yaml_files/sa_gnb_aerial/nvipc_src.YYYY.MM.DD.tar.gz ~/openairinterface5g/
|
||||
```
|
||||
|
||||
Alternatively, after running `./pack_nvipc.sh` , you can exit the container and copy `nvipc_src.YYYY.MM.DD.tar.gz` using `docker cp`
|
||||
|
||||
```bash
|
||||
~$ docker exec -it cuBB bash
|
||||
aerial@c_aerial_aerial:/opt/nvidia/cuBB# cd cuPHY-CP/gt_common_libs
|
||||
aerial@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs#./pack_nvipc.sh
|
||||
nvipc_src.YYYY.MM.DD/
|
||||
...
|
||||
---------------------------------------------
|
||||
Pack nvipc source code finished:
|
||||
/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs/nvipc_src.YYYY.MM.DD.tar.gz
|
||||
aerial@c_aerial_aerial:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs# exit
|
||||
~$ docker cp nv-cubb:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs/nvipc_src.YYYY.MM.DD.tar.gz ~/openairinterface5g
|
||||
```
|
||||
*Important note:* For using docker cp, make sure to copy the entire name of the created nvipc_src tar.gz file.
|
||||
|
||||
With the nvIPC sources in the project directory, the docker image can be built.
|
||||
|
||||
## Building OAI gNB docker image
|
||||
@@ -213,11 +230,14 @@ The process of preparing the L1 is covered on NVIDIAs' documentation, and falls
|
||||
|
||||
### Prepare the L1 image
|
||||
After preparing the L1 software, the container needs to be committed in order for an image in which the L1 is ready to be executed, and that can be referenced by a docker-compose.yaml file later:
|
||||
*Note:* In preparing the L1 image, the default L1 configuration file is cuphycontroller_P5G_FXN.yaml, located in `/opt/nvidia/cuBB/cuPHY-CP/cuphycontroller/config/`.
|
||||
This is the file where the RU MAC address needs to be applied before commiting the image
|
||||
|
||||
```bash
|
||||
~$ docker commit nv-cubb cubb-build:23-2
|
||||
~$ docker commit nv-cubb cubb-build:24-1
|
||||
~$ docker image ls
|
||||
..
|
||||
cubb-build 23-2 824156e0334c 2 weeks ago 40.1GB
|
||||
cubb-build 24-1 824156e0334c 2 weeks ago 40.1GB
|
||||
..
|
||||
```
|
||||
|
||||
@@ -237,8 +257,12 @@ Both 'GNB_IPV4_ADDRESS_FOR_NG_AMF' and 'GNB_IPV4_ADDRESS_FOR_NGU' need to be set
|
||||
|
||||
### Running docker compose
|
||||
#### Aerial L1 entrypoint script
|
||||
Before running docker-compose, we can check which L1 configuration file is to be used by cuphycontroller_scf, this is set in the script [`aerial_l1_entrypoint.sh`](../ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh), which is used by the L1 container in order to start the L1 software, this begins by installing a module 'gdrcopy', setting up some environment variables, restarting NVIDIA MPS, and finally running cuphycontroller with an argument that represent which L1 configuration file is to be used, this argument may be changed by providing an argument in docker-compose.yaml.
|
||||
When no argument is provided (this is the default behaviour), it uses "P5G_SCF_FXN" as a cuphycontroller_scf argument.
|
||||
Before running docker-compose, we can check which L1 configuration file is to be used by cuphycontroller_scf.
|
||||
This is set in the script [`aerial_l1_entrypoint.sh`](../ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh), which is used by the L1 container in order to start the L1 software.
|
||||
The script begins by setting up some environment variables, restarting NVIDIA MPS, and finally running cuphycontroller_scf.
|
||||
The L1 software is run with an argument that indicates which configuration file is to be used.
|
||||
This argument may be changed by providing an argument to the [`aerial_l1_entrypoint.sh`](../ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh) call in [`docker-compose.yaml`](../ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml).
|
||||
When no argument is provided (this is the default behaviour), it uses "P5G_FXN" as the cuphycontroller_scf argument.
|
||||
|
||||
After building the gNB image, and preparing the configuration file, the setup can be run with the following command:
|
||||
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ PROJECT_NAME = OpenAirInterface
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER =
|
||||
PROJECT_NUMBER = @GIT_COMMIT_HASH@ (@GIT_BRANCH@)
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
+138
-1
@@ -626,7 +626,7 @@ In the following, we will use these short hands:
|
||||
- `du-u-plane-mac-addr`: DU U plane MAC address
|
||||
- `pci-address-u-plane-vf`: PCI bus address of the VF for U plane
|
||||
|
||||
In the configuration file, in option `fhi_72.dpdk_devices`, the first PCI address is for C-plane and the second for U-plane.
|
||||
In the configuration file, in option `fhi_72.dpdk_devices`, the first PCI address is for U-plane and the second for C-plane.
|
||||
|
||||
For both the MAC addresses, you might use the MAC addresses which are
|
||||
pre-configured in the RUs (typically `00:11:22:33:44:66`, but that is not
|
||||
@@ -891,6 +891,143 @@ do not do any jumps (during the last hour). While an occasional jump is not
|
||||
necessarily problematic for the gNB, many such messages mean that the system is
|
||||
not working, and UEs might not be able to attach or reach good performance.
|
||||
|
||||
# Operation with multiple RUs
|
||||
|
||||
It is possible to connect up to 4 RUs to one DU at the same time and operate
|
||||
them as a (single) distributed antenna (array). This works since all RUs and
|
||||
the DU are synchronized onto a common clock using PTP. The assumed
|
||||
configuration is that with N RUs each having an M×M configuration, we
|
||||
effectively reach an (N×M)×(N×M) configuration.
|
||||
|
||||
Some caveats:
|
||||
- Since it's a distributed antenna, this implies that this setup will deploy a
|
||||
single cell only -- multiple cells on different RUs are not supported.
|
||||
- All RUs should use the same MTU, so either "normal" (1500 byte) MTU or jumbo
|
||||
frames, but not a mix of both.
|
||||
- We tested only two RUs as of now, i.e., an 8×8 configuration.
|
||||
- Testing is currently limited to 4 logical antenna ports in DL; in UL, up to 8 can be used.
|
||||
|
||||
For two RUs each using a 4x4 configuration, make sure to configure the 8x8
|
||||
configuration, i.e., set `nb_tx` and `nb_rx` under `RUs` to 8 each (NOT two
|
||||
RUs!). Also, set the antenna port information as listed above, i.e.,
|
||||
|
||||
```
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pdsch_AntennaPorts_N1 = 2;
|
||||
pusch_AntennaPorts = 8;
|
||||
maxMIMO_layers = 2;
|
||||
```
|
||||
Once testing for 8 antenna ports in DL is complete, we will change pdsch_AntennaPorts_N1 to 4.
|
||||
|
||||
Next, configure the `fhi_72` section as indicated below:
|
||||
|
||||
```
|
||||
fhi_72 = {
|
||||
dpdk_devices = ("ru1_up_vf_pci", "ru1_cp_vf_pci", "ru2_up_vf_pci", "ru2_cp_vf_pci");
|
||||
// core config as always
|
||||
du_addr = ("du_ru1_up_mac_addr", "du_ru1_cp_mac_addr", "du_ru2_up_mac_addr", "du_ru2_cp_mac_addr");
|
||||
ru_addr = ("ru1_up_mac_addr", "ru1_cp_mac_addr", "ru2_up_mac_addr", "ru2_cp_mac_addr");
|
||||
// mtu, file_prefix ...
|
||||
fh_config = (
|
||||
{
|
||||
// timing, ru_config, prach_config of RU1
|
||||
},
|
||||
{
|
||||
// timing, ru_config, prach_config of RU2
|
||||
}
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
i.e., for `dpdk_devices`, `du_addr`, and `ru_addr` is configured for
|
||||
both RUs in a (flat) array, and the individual radio configuration is given for
|
||||
each RU individually inside the `fh_config`.
|
||||
|
||||
<details>
|
||||
<summary>Sample FHI 7.2 configuration for two RUs (Benetel 550 and 650)</summary>
|
||||
|
||||
```
|
||||
fhi_72 = {
|
||||
dpdk_devices = ("0000:01:01.0", "0000:01:01.1", "0000:01:01.2", "0000:01:01.3");
|
||||
system_core = 0;
|
||||
io_core = 1;
|
||||
worker_cores = (2);
|
||||
du_addr = ("00:11:22:33:44:66","00:11:22:33:44:67","00:11:22:33:44:66","00:11:22:33:44:67");
|
||||
ru_addr = ("70:b3:d5:e1:5b:ff","70:b3:d5:e1:5b:ff","70:b3:d5:e1:5b:81", "70:b3:d5:e1:5b:81");
|
||||
mtu = 9216;
|
||||
file_prefix = "fhi_72";
|
||||
fh_config = (
|
||||
# RAN650
|
||||
{
|
||||
Tadv_cp_dl = 125;
|
||||
T2a_cp_dl = (259, 500);
|
||||
T2a_cp_ul = (25, 500);
|
||||
T2a_up = (134, 375);
|
||||
Ta3 = (152, 160);
|
||||
T1a_cp_dl = (419, 470);
|
||||
T1a_cp_ul = (285, 336);
|
||||
T1a_up = (294, 345);
|
||||
Ta4 = (0, 200);
|
||||
ru_config = {
|
||||
iq_width = 9;
|
||||
iq_width_prach = 9;
|
||||
};
|
||||
prach_config = {
|
||||
eAxC_offset = 4;
|
||||
};
|
||||
},
|
||||
# RAN550
|
||||
{
|
||||
Tadv_cp_dl = 125;
|
||||
T2a_cp_dl = (259, 500);
|
||||
T2a_cp_ul = (25, 500);
|
||||
T2a_up = (134, 375);
|
||||
Ta3 = (152, 160);
|
||||
T1a_cp_dl = (419, 470);
|
||||
T1a_cp_ul = (285, 336);
|
||||
T1a_up = (294, 345);
|
||||
Ta4 = (0, 200);
|
||||
ru_config = {
|
||||
iq_width = 9;
|
||||
iq_width_prach = 9;
|
||||
};
|
||||
prach_config = {
|
||||
eAxC_offset = 4;
|
||||
};
|
||||
});
|
||||
```
|
||||
</details>
|
||||
|
||||
Compare also with the example (DU) configuration in
|
||||
[`gnb-du.sa.band78.106prb.fhi72.8x8-benetel-650-550.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band78.106prb.fhi72.8x8-benetel-650-550.conf).
|
||||
|
||||
Afterwards, start the gNB with the modified configuration file. If everything
|
||||
went well, you should see the RU counters for both RUs go up:
|
||||
|
||||
```
|
||||
[NR_PHY] [o-du 0][rx 614400 pps 61440 kbps 844953][tx 1275076 pps 127488 kbps 1998585][Total Msgs_Rcvd 614400]
|
||||
[NR_PHY] [o_du0][pusch0 107520 prach0 46080]
|
||||
[NR_PHY] [o_du0][pusch1 107520 prach1 46080]
|
||||
[NR_PHY] [o_du0][pusch2 107520 prach2 46080]
|
||||
[NR_PHY] [o_du0][pusch3 107520 prach3 46080]
|
||||
[NR_PHY] [o-du 1][rx 614400 pps 61440 kbps 844953][tx 1275076 pps 127488 kbps 1998585][Total Msgs_Rcvd 614400]
|
||||
[NR_PHY] [o_du1][pusch0 107520 prach0 46080]
|
||||
[NR_PHY] [o_du1][pusch1 107520 prach1 46080]
|
||||
[NR_PHY] [o_du1][pusch2 107520 prach2 46080]
|
||||
[NR_PHY] [o_du1][pusch3 107520 prach3 46080]
|
||||
```
|
||||
|
||||
You can also verify that there is signal on all RX antennas like so:
|
||||
```bash
|
||||
$ cat nrL1_stats.log
|
||||
[...]
|
||||
max_IO = 66 (81), min_I0 = 0 (53), avg_I0 = 51 dB(46.48.45.46.51.56.55.45.)
|
||||
PRACH I0 = 38.0 dB
|
||||
```
|
||||
|
||||
Note the eight entries after `avg_IO`.
|
||||
|
||||
You should be able to connect a UE now.
|
||||
|
||||
# Contact in case of questions
|
||||
|
||||
|
||||
@@ -107,3 +107,65 @@ that directory directly, which you might also use to compare to the
|
||||
slight complication is due to using shell scripts. An easier way is to
|
||||
directly declare the executable in `add_test()`, and `ctest` will locate and
|
||||
run the executable properly.
|
||||
|
||||
# Benchmarking
|
||||
|
||||
Google benchmark can be used to profile and benchmark small pieces of code. See
|
||||
`benchmark_rotate_vector` for reference implementation. To start benchmarking code,
|
||||
write a benchmark first and compare your implementation against baseline result.
|
||||
To ensure your results are reproducible see this [guide](https://github.com/google/benchmark/blob/main/docs/reducing_variance.md)
|
||||
|
||||
Example output follows:
|
||||
|
||||
```bash
|
||||
2024-08-26T11:55:49+02:00
|
||||
Running ./openair1/PHY/TOOLS/tests/benchmark_rotate_vector
|
||||
Run on (8 X 4700 MHz CPU s)
|
||||
CPU Caches:
|
||||
L1 Data 48 KiB (x4)
|
||||
L1 Instruction 32 KiB (x4)
|
||||
L2 Unified 1280 KiB (x4)
|
||||
L3 Unified 12288 KiB (x1)
|
||||
Load Average: 0.51, 0.31, 0.29
|
||||
***WARNING*** CPU scaling is enabled, the benchmark real time measurements may be noisy and will incur extra overhead.
|
||||
---------------------------------------------------------------------
|
||||
Benchmark Time CPU Iterations
|
||||
---------------------------------------------------------------------
|
||||
BM_rotate_cpx_vector/100 43.1 ns 43.1 ns 16683136
|
||||
BM_rotate_cpx_vector/256 70.1 ns 70.0 ns 9647446
|
||||
BM_rotate_cpx_vector/1024 277 ns 277 ns 2378273
|
||||
BM_rotate_cpx_vector/4096 1070 ns 1070 ns 654792
|
||||
BM_rotate_cpx_vector/16384 4220 ns 4220 ns 169070
|
||||
BM_rotate_cpx_vector/20000 5288 ns 5289 ns 136190
|
||||
```
|
||||
|
||||
## Comparing results
|
||||
|
||||
Benchmark results can be output to json by using command line arguments, example below
|
||||
|
||||
```bash
|
||||
./benchmark_rotate_vector --benchmark_out=file.json --benchmark_repetitions=10
|
||||
```
|
||||
|
||||
These results can be compared by a tool provided with google benchmark
|
||||
|
||||
```bash
|
||||
./compare.py benchmarks ../../file.json ../../file1.json
|
||||
```
|
||||
|
||||
Example output:
|
||||
```
|
||||
Comparing ../../file.json to ../../file1.json
|
||||
Benchmark Time CPU Time Old Time New CPU Old CPU New
|
||||
--------------------------------------------------------------------------------------------------------------------------------
|
||||
BM_rotate_cpx_vector/100 +0.3383 +0.3384 43 58 43 58
|
||||
BM_rotate_cpx_vector/100 +0.2334 +0.2335 42 52 42 52
|
||||
BM_rotate_cpx_vector/100 +0.1685 +0.1683 42 49 42 49
|
||||
BM_rotate_cpx_vector/100 +0.1890 +0.1889 42 50 42 50
|
||||
BM_rotate_cpx_vector/100 +0.0456 +0.0457 42 44 42 44
|
||||
BM_rotate_cpx_vector/100 +0.0163 +0.0162 42 42 42 42
|
||||
BM_rotate_cpx_vector/100 +0.0005 +0.0004 43 43 43 43
|
||||
BM_rotate_cpx_vector/100 +0.0134 +0.0129 43 43 43 43
|
||||
BM_rotate_cpx_vector/100 +0.0162 +0.0162 42 42 42 42
|
||||
BM_rotate_cpx_vector/100 +0.0003 +0.0003 42 42 42 42
|
||||
```
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
|
||||
|
||||
#include "assertions.h"
|
||||
#include "common/oai_version.h"
|
||||
|
||||
#include "PHY/types.h"
|
||||
|
||||
@@ -466,11 +467,8 @@ int main ( int argc, char **argv )
|
||||
init_opt();
|
||||
// to make a graceful exit when ctrl-c is pressed
|
||||
set_softmodem_sighandler();
|
||||
#ifndef PACKAGE_VERSION
|
||||
#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#endif
|
||||
// strdup to put the sring in the core file for post mortem identification
|
||||
LOG_I(HW, "Version: %s\n", strdup(PACKAGE_VERSION));
|
||||
LOG_I(HW, "Version: %s\n", strdup(OAI_PACKAGE_VERSION));
|
||||
|
||||
/* Read configuration */
|
||||
if (RC.nb_inst > 0) {
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "pdcp.h"
|
||||
|
||||
#include "PHY/defs_UE.h"
|
||||
#include "common/oai_version.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "common/config/config_userapi.h"
|
||||
#include "common/utils/load_module_shlib.h"
|
||||
@@ -575,11 +576,8 @@ int main( int argc, char **argv ) {
|
||||
pdcp_pc5_socket_init();
|
||||
// to make a graceful exit when ctrl-c is pressed
|
||||
set_softmodem_sighandler();
|
||||
#ifndef PACKAGE_VERSION
|
||||
#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#endif
|
||||
// strdup to put the sring in the core file for post mortem identification
|
||||
LOG_I(HW, "Version: %s\n", strdup(PACKAGE_VERSION));
|
||||
LOG_I(HW, "Version: %s\n", strdup(OAI_PACKAGE_VERSION));
|
||||
|
||||
// init the parameters
|
||||
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "PHY/types.h"
|
||||
|
||||
#include "PHY/defs_RU.h"
|
||||
#include "common/oai_version.h"
|
||||
#include "common/config/config_userapi.h"
|
||||
#include "common/utils/load_module_shlib.h"
|
||||
|
||||
@@ -160,11 +161,8 @@ int main ( int argc, char **argv )
|
||||
T_Config_Init();
|
||||
#endif
|
||||
printf("configuring for RRU\n");
|
||||
#ifndef PACKAGE_VERSION
|
||||
#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#endif
|
||||
// strdup to put the sring in the core file for post mortem identification
|
||||
LOG_I(HW, "Version: %s\n", strdup(PACKAGE_VERSION));
|
||||
LOG_I(HW, "Version: %s\n", strdup(OAI_PACKAGE_VERSION));
|
||||
|
||||
/* Read configuration */
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "common/oai_version.h"
|
||||
#include "common/utils/simple_executable.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "common/utils/ocp_itti/intertask_interface.h"
|
||||
@@ -156,11 +157,8 @@ int main(int argc, char **argv)
|
||||
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
|
||||
}
|
||||
logInit();
|
||||
#ifndef PACKAGE_VERSION
|
||||
#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#endif
|
||||
// strdup to put the sring in the core file for post mortem identification
|
||||
LOG_I(HW, "Version: %s\n", strdup(PACKAGE_VERSION));
|
||||
LOG_I(HW, "Version: %s\n", strdup(OAI_PACKAGE_VERSION));
|
||||
set_softmodem_sighandler();
|
||||
itti_init(TASK_MAX, tasks_info);
|
||||
int rc;
|
||||
|
||||
@@ -497,8 +497,7 @@ void init_gNB(int wait_for_sync) {
|
||||
RC.gNB[inst] = (PHY_VARS_gNB *) calloc(1, sizeof(PHY_VARS_gNB));
|
||||
LOG_I(PHY,"[nr-gnb.c] gNB structure RC.gNB[%d] allocated @ %p\n",inst,RC.gNB[inst]);
|
||||
}
|
||||
gNB = RC.gNB[inst];
|
||||
gNB->abstraction_flag = 0;
|
||||
gNB = RC.gNB[inst];
|
||||
/*nr_polar_init(&gNB->nrPolar_params,
|
||||
NR_POLAR_PBCH_MESSAGE_TYPE,
|
||||
NR_POLAR_PBCH_PAYLOAD_BITS,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
|
||||
#include <common/utils/assertions.h>
|
||||
#include "common/oai_version.h"
|
||||
|
||||
#include "PHY/types.h"
|
||||
#include "common/ran_context.h"
|
||||
@@ -162,11 +163,6 @@ void pdcp_run(const protocol_ctxt_t *const ctxt_pP)
|
||||
abort();
|
||||
}
|
||||
|
||||
/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed
|
||||
* this is very hackish - find a proper solution
|
||||
*/
|
||||
uint8_t abstraction_flag=0;
|
||||
|
||||
/* forward declarations */
|
||||
void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs], NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
|
||||
|
||||
@@ -644,11 +640,8 @@ int main( int argc, char **argv ) {
|
||||
// initialize mscgen log after ITTI
|
||||
init_opt();
|
||||
|
||||
#ifndef PACKAGE_VERSION
|
||||
#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#endif
|
||||
// strdup to put the sring in the core file for post mortem identification
|
||||
char *pckg = strdup(PACKAGE_VERSION);
|
||||
char *pckg = strdup(OAI_PACKAGE_VERSION);
|
||||
LOG_I(HW, "Version: %s\n", pckg);
|
||||
|
||||
// don't create if node doesn't connect to RRC/S1/GTP
|
||||
|
||||
+2
-5
@@ -445,10 +445,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action)
|
||||
|
||||
radio_tx_burst_flag_t flags = TX_BURST_INVALID;
|
||||
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(UE->Mod_id);
|
||||
if (mac->phy_config_request_sent &&
|
||||
openair0_cfg[0].duplex_mode == duplex_mode_TDD &&
|
||||
!get_softmodem_params()->continuous_tx) {
|
||||
if (UE->received_config_request && openair0_cfg[0].duplex_mode == duplex_mode_TDD && !get_softmodem_params()->continuous_tx) {
|
||||
// In case of Sidelink, USRP write needed only in case transmission
|
||||
// needs to be done in this slot and not based on tdd ULDL configuration.
|
||||
if (UE->sl_mode == 2) {
|
||||
@@ -930,7 +927,7 @@ void *UE_thread(void *arg)
|
||||
curMsg.proc.nr_slot_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame;
|
||||
curMsg.proc.frame_rx = (absolute_slot / nb_slot_frame) % MAX_FRAME_NUMBER;
|
||||
curMsg.proc.frame_tx = ((absolute_slot + DURATION_RX_TO_TX) / nb_slot_frame) % MAX_FRAME_NUMBER;
|
||||
if (mac->phy_config_request_sent) {
|
||||
if (UE->received_config_request) {
|
||||
if (UE->sl_mode) {
|
||||
curMsg.proc.rx_slot_type = sl_nr_ue_slot_select(sl_cfg, curMsg.proc.nr_slot_rx, TDD);
|
||||
curMsg.proc.tx_slot_type = sl_nr_ue_slot_select(sl_cfg, curMsg.proc.nr_slot_tx, TDD);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <signal.h>
|
||||
|
||||
#include "T.h"
|
||||
#include "common/oai_version.h"
|
||||
#include "assertions.h"
|
||||
#include "PHY/types.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
@@ -430,11 +431,8 @@ int main(int argc, char **argv)
|
||||
if (ouput_vcd) {
|
||||
vcd_signal_dumper_init("/tmp/openair_dump_nrUE.vcd");
|
||||
}
|
||||
#ifndef PACKAGE_VERSION
|
||||
#define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
|
||||
#endif
|
||||
// strdup to put the sring in the core file for post mortem identification
|
||||
char *pckg = strdup(PACKAGE_VERSION);
|
||||
char *pckg = strdup(OAI_PACKAGE_VERSION);
|
||||
LOG_I(HW, "Version: %s\n", pckg);
|
||||
|
||||
PHY_vars_UE_g = malloc(sizeof(*PHY_vars_UE_g) * NB_UE_INST);
|
||||
@@ -493,11 +491,7 @@ int main(int argc, char **argv)
|
||||
get_softmodem_params()->numerology,
|
||||
nr_band);
|
||||
} else {
|
||||
DevAssert(mac->if_module != NULL && mac->if_module->phy_config_request != NULL);
|
||||
mac->if_module->phy_config_request(&mac->phy_config);
|
||||
mac->phy_config_request_sent = true;
|
||||
fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config;
|
||||
|
||||
nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, mac->nr_band);
|
||||
}
|
||||
|
||||
@@ -511,7 +505,6 @@ int main(int argc, char **argv)
|
||||
phycfg->sl_config_req.sl_carrier_config.sl_num_rx_ant = get_nrUE_params()->nb_antennas_rx;
|
||||
phycfg->sl_config_req.sl_carrier_config.sl_num_tx_ant = get_nrUE_params()->nb_antennas_tx;
|
||||
mac->if_module->sl_phy_config_request(phycfg);
|
||||
mac->phy_config_request_sent = true;
|
||||
sl_nr_ue_phy_params_t *sl_phy = &UE[CC_id]->SL_UE_PHY_PARAMS;
|
||||
nr_init_frame_parms_ue_sl(&sl_phy->sl_frame_params,
|
||||
&sl_phy->sl_config,
|
||||
|
||||
@@ -260,9 +260,8 @@ void oai_create_gnb(void) {
|
||||
PHY_VARS_gNB *gNB = RC.gNB[0];
|
||||
RC.nb_nr_CC = (int *)malloc(sizeof(int)); // TODO: find a better function to place this in
|
||||
|
||||
gNB->Mod_id = bodge_counter;
|
||||
gNB->CC_id = bodge_counter;
|
||||
gNB->abstraction_flag = 0;
|
||||
gNB->Mod_id = bodge_counter;
|
||||
gNB->CC_id = bodge_counter;
|
||||
RC.nb_nr_CC[bodge_counter] = 1;
|
||||
|
||||
if (gNB->if_inst==0) {
|
||||
|
||||
@@ -31,7 +31,7 @@ PROJECT_NAME = @PACKAGE_NAME@
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = @PACKAGE_VERSION@
|
||||
PROJECT_NUMBER = @GIT_COMMIT_HASH@
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "common/oai_version.h"
|
||||
|
||||
#include "PHY/sse_intrin.h"
|
||||
|
||||
@@ -359,10 +360,7 @@ void init_encoder_sse (void) {
|
||||
against main exec version. version mismatch no considered as fatal (interfaces not supposed to change)
|
||||
*/
|
||||
int coding_checkbuildver(char *mainexec_buildversion, char **shlib_buildversion) {
|
||||
#ifndef PACKAGE_VERSION
|
||||
#define PACKAGE_VERSION "standalone built: " __DATE__ __TIME__
|
||||
#endif
|
||||
*shlib_buildversion = PACKAGE_VERSION;
|
||||
*shlib_buildversion = OAI_PACKAGE_VERSION;
|
||||
|
||||
if (strcmp(mainexec_buildversion, *shlib_buildversion) != 0) {
|
||||
fprintf(stderr,"[CODING] shared lib version %s, doesn't match main version %s, compatibility should be checked\n",
|
||||
|
||||
@@ -85,138 +85,119 @@
|
||||
#include "ldpc_BG2_Zc80_byte.c"
|
||||
#include "ldpc_BG2_Zc72_byte.c"
|
||||
|
||||
|
||||
|
||||
static void encode_parity_check_part_optim(uint8_t *cc,uint8_t *d, short BG,short Zc,short Kb, int simd_size, int ncols)
|
||||
static void encode_parity_check_part_optim(uint8_t *cc, uint8_t *d, short BG,short Zc,short Kb, int simd_size, int ncols)
|
||||
{
|
||||
unsigned char c[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c
|
||||
for (int i1=0; i1 < ncols; i1++) {
|
||||
memcpy(&c[2*i1*Zc], &cc[i1*Zc], Zc*sizeof(unsigned char));
|
||||
memcpy(&c[(2*i1+1)*Zc], &cc[i1*Zc], Zc*sizeof(unsigned char));
|
||||
unsigned char c[2 * 22 * Zc * simd_size] __attribute__((aligned(32))); //double size matrix of c
|
||||
for (int i1 = 0; i1 < ncols; i1++) {
|
||||
memcpy(&c[2 * i1 * Zc], &cc[i1 * Zc], Zc * sizeof(unsigned char));
|
||||
memcpy(&c[(2 * i1 + 1) * Zc], &cc[i1 * Zc], Zc * sizeof(unsigned char));
|
||||
}
|
||||
for (int i1=1;i1<simd_size;i1++) {
|
||||
memcpy(&c[(2*ncols*Zc*i1)], &c[i1], (2*ncols*Zc*sizeof(unsigned char))-i1);
|
||||
for (int i1 = 1; i1 < simd_size; i1++) {
|
||||
memcpy(&c[(2 * ncols * Zc * i1)], &c[i1], (2 * ncols * Zc * sizeof(unsigned char)) - i1);
|
||||
}
|
||||
|
||||
if (BG==1)
|
||||
{
|
||||
switch (Zc)
|
||||
{
|
||||
case 2: break;
|
||||
case 3: break;
|
||||
case 4: break;
|
||||
case 5: break;
|
||||
case 6: break;
|
||||
case 7: break;
|
||||
case 8: break;
|
||||
case 9: break;
|
||||
case 10: break;
|
||||
case 11: break;
|
||||
case 12: break;
|
||||
case 13: break;
|
||||
case 14: break;
|
||||
case 15: break;
|
||||
case 16: break;
|
||||
case 18: break;
|
||||
case 20: break;
|
||||
case 22: break;
|
||||
case 24: break;
|
||||
case 26: break;
|
||||
case 28: break;
|
||||
case 30: break;
|
||||
case 32: break;
|
||||
case 36: break;
|
||||
case 40: break;
|
||||
case 44: break;
|
||||
case 48: break;
|
||||
case 52: break;
|
||||
case 56: break;
|
||||
case 60: break;
|
||||
case 64: break;
|
||||
case 72: break;
|
||||
case 80: break;
|
||||
case 88: break;
|
||||
case 96: break;
|
||||
case 104: break;
|
||||
case 112: break;
|
||||
case 120: break;
|
||||
case 128: break;
|
||||
case 144: break;
|
||||
case 160: break;
|
||||
case 176: ldpc176_byte(c,d); break;
|
||||
case 192: ldpc192_byte(c,d); break;
|
||||
case 208: ldpc208_byte(c,d); break;
|
||||
case 224: ldpc224_byte(c,d); break;
|
||||
case 240: ldpc240_byte(c,d); break;
|
||||
case 256: ldpc256_byte(c,d); break;
|
||||
case 288: ldpc288_byte(c,d); break;
|
||||
case 320: ldpc320_byte(c,d); break;
|
||||
case 352: ldpc352_byte(c,d); break;
|
||||
case 384: ldpc384_byte(c,d); break;
|
||||
default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break;
|
||||
if (BG == 1) {
|
||||
switch (Zc) {
|
||||
case 176:
|
||||
ldpc176_byte(c, d);
|
||||
break;
|
||||
case 192:
|
||||
ldpc192_byte(c, d);
|
||||
break;
|
||||
case 208:
|
||||
ldpc208_byte(c, d);
|
||||
break;
|
||||
case 224:
|
||||
ldpc224_byte(c, d);
|
||||
break;
|
||||
case 240:
|
||||
ldpc240_byte(c, d);
|
||||
break;
|
||||
case 256:
|
||||
ldpc256_byte(c, d);
|
||||
break;
|
||||
case 288:
|
||||
ldpc288_byte(c, d);
|
||||
break;
|
||||
case 320:
|
||||
ldpc320_byte(c, d);
|
||||
break;
|
||||
case 352:
|
||||
ldpc352_byte(c, d);
|
||||
break;
|
||||
case 384:
|
||||
ldpc384_byte(c, d);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "BG %d Zc %d is not supported yet\n", BG, Zc);
|
||||
}
|
||||
}
|
||||
else if (BG==2) {
|
||||
switch (Zc)
|
||||
{
|
||||
case 2: break;
|
||||
case 3: break;
|
||||
case 4: break;
|
||||
case 5: break;
|
||||
case 6: break;
|
||||
case 7: break;
|
||||
case 8: break;
|
||||
case 9: break;
|
||||
case 10: break;
|
||||
case 11: break;
|
||||
case 12: break;
|
||||
case 13: break;
|
||||
case 14: break;
|
||||
case 15: break;
|
||||
case 16: break;
|
||||
case 18: break;
|
||||
case 20: break;
|
||||
case 22: break;
|
||||
case 24: break;
|
||||
case 26: break;
|
||||
case 28: break;
|
||||
case 30: break;
|
||||
case 32: break;
|
||||
case 36: break;
|
||||
case 40: break;
|
||||
case 44: break;
|
||||
case 48: break;
|
||||
case 52: break;
|
||||
case 56: break;
|
||||
case 60: break;
|
||||
case 64: break;
|
||||
case 72: ldpc_BG2_Zc72_byte(c,d); break;
|
||||
case 80: ldpc_BG2_Zc80_byte(c,d); break;
|
||||
case 88: ldpc_BG2_Zc88_byte(c,d); break;
|
||||
case 96: ldpc_BG2_Zc96_byte(c,d); break;
|
||||
case 104: ldpc_BG2_Zc104_byte(c,d); break;
|
||||
case 112: ldpc_BG2_Zc112_byte(c,d); break;
|
||||
case 120: ldpc_BG2_Zc120_byte(c,d); break;
|
||||
case 128: ldpc_BG2_Zc128_byte(c,d); break;
|
||||
case 144: ldpc_BG2_Zc144_byte(c,d); break;
|
||||
case 160: ldpc_BG2_Zc160_byte(c,d); break;
|
||||
case 176: ldpc_BG2_Zc176_byte(c,d); break;
|
||||
case 192: ldpc_BG2_Zc192_byte(c,d); break;
|
||||
case 208: ldpc_BG2_Zc208_byte(c,d); break;
|
||||
case 224: ldpc_BG2_Zc224_byte(c,d); break;
|
||||
case 240: ldpc_BG2_Zc240_byte(c,d); break;
|
||||
case 256: ldpc_BG2_Zc256_byte(c,d); break;
|
||||
case 288: ldpc_BG2_Zc288_byte(c,d); break;
|
||||
case 320: ldpc_BG2_Zc320_byte(c,d); break;
|
||||
case 352: ldpc_BG2_Zc352_byte(c,d); break;
|
||||
case 384: ldpc_BG2_Zc384_byte(c,d); break;
|
||||
default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break;
|
||||
} else if (BG == 2) {
|
||||
switch (Zc) {
|
||||
case 72:
|
||||
ldpc_BG2_Zc72_byte(c, d);
|
||||
break;
|
||||
case 80:
|
||||
ldpc_BG2_Zc80_byte(c, d);
|
||||
break;
|
||||
case 88:
|
||||
ldpc_BG2_Zc88_byte(c, d);
|
||||
break;
|
||||
case 96:
|
||||
ldpc_BG2_Zc96_byte(c, d);
|
||||
break;
|
||||
case 104:
|
||||
ldpc_BG2_Zc104_byte(c, d);
|
||||
break;
|
||||
case 112:
|
||||
ldpc_BG2_Zc112_byte(c, d);
|
||||
break;
|
||||
case 120:
|
||||
ldpc_BG2_Zc120_byte(c, d);
|
||||
break;
|
||||
case 128:
|
||||
ldpc_BG2_Zc128_byte(c, d);
|
||||
break;
|
||||
case 144:
|
||||
ldpc_BG2_Zc144_byte(c, d);
|
||||
break;
|
||||
case 160:
|
||||
ldpc_BG2_Zc160_byte(c, d);
|
||||
break;
|
||||
case 176:
|
||||
ldpc_BG2_Zc176_byte(c, d);
|
||||
break;
|
||||
case 192:
|
||||
ldpc_BG2_Zc192_byte(c, d);
|
||||
break;
|
||||
case 208:
|
||||
ldpc_BG2_Zc208_byte(c, d);
|
||||
break;
|
||||
case 224:
|
||||
ldpc_BG2_Zc224_byte(c, d);
|
||||
break;
|
||||
case 240:
|
||||
ldpc_BG2_Zc240_byte(c, d);
|
||||
break;
|
||||
case 256:
|
||||
ldpc_BG2_Zc256_byte(c, d);
|
||||
break;
|
||||
case 288:
|
||||
ldpc_BG2_Zc288_byte(c, d);
|
||||
break;
|
||||
case 320:
|
||||
ldpc_BG2_Zc320_byte(c, d);
|
||||
break;
|
||||
case 352:
|
||||
ldpc_BG2_Zc352_byte(c, d);
|
||||
break;
|
||||
case 384:
|
||||
ldpc_BG2_Zc384_byte(c, d);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false , "BG %d Zc %d is not supported yet\n", BG, Zc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
AssertFatal(0,"BG %d is not supported yet\n",BG);
|
||||
}
|
||||
|
||||
} else
|
||||
AssertFatal(false, "BG %d is not supported\n", BG);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ int LDPCencoder(uint8_t **test_input, uint8_t **channel_input, encoder_implempar
|
||||
|
||||
if(impp->tinput != NULL) stop_meas(impp->tinput);
|
||||
|
||||
if ((BG==1 && Zc>=176) || (BG==2 && Zc>=64)) {
|
||||
if ((BG==1 && Zc>=176) || (BG==2 && Zc>=72)) {
|
||||
// extend matrix
|
||||
if(impp->tprep != NULL) start_meas(impp->tprep);
|
||||
if(impp->tprep != NULL) stop_meas(impp->tprep);
|
||||
|
||||
@@ -143,7 +143,7 @@ int LDPCencoder(uint8_t **test_input, uint8_t **channel_input, encoder_implempar
|
||||
|
||||
if(impp->tinput != NULL) stop_meas(impp->tinput);
|
||||
|
||||
if ((BG==1 && Zc>=176) || (BG==2 && Zc>=64)) {
|
||||
if ((BG==1 && Zc>=176) || (BG==2 && Zc>=72)) {
|
||||
// extend matrix
|
||||
if(impp->tprep != NULL) start_meas(impp->tprep);
|
||||
if(impp->tprep != NULL) stop_meas(impp->tprep);
|
||||
|
||||
@@ -151,7 +151,7 @@ int LDPCencoder(uint8_t **input, uint8_t **output, encoder_implemparams_t *impp)
|
||||
|
||||
if(impp->tinput != NULL) stop_meas(impp->tinput);
|
||||
|
||||
if ((BG==1 && Zc>=176) || (BG==2 && Zc>=64)) {
|
||||
if ((BG==1 && Zc>=176) || (BG==2 && Zc>=72)) {
|
||||
// extend matrix
|
||||
if(impp->tprep != NULL) start_meas(impp->tprep);
|
||||
if(impp->tprep != NULL) stop_meas(impp->tprep);
|
||||
|
||||
@@ -190,7 +190,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
common_vars->debugBuff_sample_offset = 0;
|
||||
|
||||
// PRACH
|
||||
prach_vars->prachF = (int16_t *)malloc16_clear( 1024*2*sizeof(int16_t) );
|
||||
prach_vars->rxsigF = (int16_t **)malloc16_clear(Prx*sizeof(int16_t*));
|
||||
prach_vars->prach_ifft = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t));
|
||||
|
||||
@@ -205,19 +204,13 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
gNB->pusch_vars = (NR_gNB_PUSCH *)malloc16_clear(gNB->max_nb_pusch * sizeof(NR_gNB_PUSCH));
|
||||
for (int ULSCH_id = 0; ULSCH_id < gNB->max_nb_pusch; ULSCH_id++) {
|
||||
NR_gNB_PUSCH *pusch = &gNB->pusch_vars[ULSCH_id];
|
||||
pusch->rxdataF_ext = (int32_t **)malloc16(Prx * sizeof(int32_t *));
|
||||
pusch->ul_ch_estimates = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
|
||||
pusch->ul_ch_estimates_ext = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
|
||||
pusch->ptrs_phase_per_slot = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
|
||||
pusch->ul_ch_estimates_time = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
|
||||
pusch->rxdataF_comp = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
|
||||
pusch->llr_layers = (int16_t **)malloc16(max_ul_mimo_layers * sizeof(int32_t *));
|
||||
for (i = 0; i < Prx; i++) {
|
||||
pusch->rxdataF_ext[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
|
||||
}
|
||||
for (i = 0; i < n_buf; i++) {
|
||||
pusch->ul_ch_estimates[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->ofdm_symbol_size * fp->symbols_per_slot);
|
||||
pusch->ul_ch_estimates_ext[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
|
||||
pusch->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->ofdm_symbol_size);
|
||||
pusch->ptrs_phase_per_slot[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->symbols_per_slot); // symbols per slot
|
||||
pusch->rxdataF_comp[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
|
||||
@@ -279,7 +272,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
free_and_zero(common_vars->debugBuff);
|
||||
|
||||
NR_gNB_PRACH* prach_vars = &gNB->prach_vars;
|
||||
free_and_zero(prach_vars->prachF);
|
||||
free_and_zero(prach_vars->rxsigF);
|
||||
free_and_zero(prach_vars->prach_ifft);
|
||||
|
||||
@@ -287,20 +279,14 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ULSCH_id];
|
||||
for (int i=0; i< max_ul_mimo_layers; i++)
|
||||
free_and_zero(pusch_vars->llr_layers[i]);
|
||||
for (int i = 0; i < Prx; i++) {
|
||||
free_and_zero(pusch_vars->rxdataF_ext[i]);
|
||||
}
|
||||
for (int i = 0; i < n_buf; i++) {
|
||||
free_and_zero(pusch_vars->ul_ch_estimates[i]);
|
||||
free_and_zero(pusch_vars->ul_ch_estimates_ext[i]);
|
||||
free_and_zero(pusch_vars->ul_ch_estimates_time[i]);
|
||||
free_and_zero(pusch_vars->ptrs_phase_per_slot[i]);
|
||||
free_and_zero(pusch_vars->rxdataF_comp[i]);
|
||||
}
|
||||
free_and_zero(pusch_vars->llr_layers);
|
||||
free_and_zero(pusch_vars->rxdataF_ext);
|
||||
free_and_zero(pusch_vars->ul_ch_estimates);
|
||||
free_and_zero(pusch_vars->ul_ch_estimates_ext);
|
||||
free_and_zero(pusch_vars->ptrs_phase_per_slot);
|
||||
free_and_zero(pusch_vars->ul_ch_estimates_time);
|
||||
free_and_zero(pusch_vars->ul_valid_re_per_slot);
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "PHY/NR_REFSIG/nr_mod_table.h"
|
||||
#include "openair2/COMMON/prs_nr_paramdef.h"
|
||||
#include "SCHED_NR_UE/harq_nr.h"
|
||||
#include "nr-uesoftmodem.h"
|
||||
|
||||
void RCconfig_nrUE_prs(void *cfg)
|
||||
{
|
||||
@@ -277,15 +278,14 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
}
|
||||
|
||||
ue->init_averaging = 1;
|
||||
|
||||
// enable MIB/SIB decoding by default
|
||||
ue->decode_MIB = 1;
|
||||
ue->decode_SIB = 1;
|
||||
|
||||
init_nr_prach_tables(839);
|
||||
init_symbol_rotation(fp);
|
||||
init_timeshift_rotation(fp);
|
||||
|
||||
// initialize to false only for SA since in do-ra and phy-test it is already set to true before getting here
|
||||
if (get_softmodem_params()->sa)
|
||||
ue->received_config_request = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+167
-134
@@ -47,12 +47,13 @@ const uint8_t nr_pbch_payload_interleaving_pattern[32] = {16, 23, 18, 17, 8, 30,
|
||||
9, 11, 12, 13, 14, 15, 19, 20, 21, 22, 25, 26, 27, 28, 29, 31
|
||||
};
|
||||
|
||||
int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
c16_t *txdataF,
|
||||
int16_t amp,
|
||||
uint8_t ssb_start_symbol,
|
||||
nfapi_nr_config_request_scf_t *config,
|
||||
NR_DL_FRAME_PARMS *frame_parms) {
|
||||
void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
c16_t *txdataF,
|
||||
int16_t amp,
|
||||
uint8_t ssb_start_symbol,
|
||||
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];
|
||||
@@ -139,186 +140,220 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
#ifdef DEBUG_PBCH_DMRS
|
||||
write_output("txdataF_pbch_dmrs.m", "txdataF_pbch_dmrs", txdataF[0], frame_parms->samples_per_frame_wCP>>1, 1, 1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
|
||||
uint32_t Nid,
|
||||
uint8_t nushift,
|
||||
uint16_t M,
|
||||
uint16_t length,
|
||||
uint8_t encoded,
|
||||
uint32_t unscrambling_mask)
|
||||
{
|
||||
uint32_t *pbch_e = pbch->pbch_e;
|
||||
// x1 is set in lte_gold_generic
|
||||
typedef struct {
|
||||
int len;
|
||||
int goldIdx;
|
||||
int offset;
|
||||
} NR_PBCH_scramb_info_t;
|
||||
|
||||
const int len = (nushift * M + 31) / 32 + (length + 31) / 32;
|
||||
uint32_t *s = gold_cache(Nid, len);
|
||||
static NR_PBCH_scramb_info_t get_scrambling_info(uint8_t nushift,
|
||||
uint16_t M,
|
||||
uint16_t length)
|
||||
{
|
||||
NR_PBCH_scramb_info_t info;
|
||||
info.len = (nushift * M + 31) / 32 + (length + 31) / 32;
|
||||
// The Gold sequence is shifted by nushift* M, so we skip (nushift*M /32) double words
|
||||
int goldIdx = (nushift * M + 31) / 32 - 1;
|
||||
info.goldIdx = (nushift * M + 31) / 32 - 1;
|
||||
// Scrambling is now done with offset (nushift*M)%32
|
||||
uint8_t offset = (nushift * M) & 0x1f;
|
||||
info.offset = (nushift * M) & 0x1f;
|
||||
return info;
|
||||
}
|
||||
|
||||
static void nr_pbch_encoded_scrambling(uint32_t *pbch_e,
|
||||
uint32_t Nid,
|
||||
uint8_t nushift,
|
||||
uint16_t M,
|
||||
uint16_t length)
|
||||
{
|
||||
NR_PBCH_scramb_info_t info = get_scrambling_info(nushift, M, length);
|
||||
uint32_t *s = gold_cache(Nid, info.len);
|
||||
int goldIdx = info.goldIdx;
|
||||
#ifdef DEBUG_PBCH_ENCODING
|
||||
printf("Scrambling params: nushift %d M %d length %d encoded %d offset %d\n", nushift, M, length, encoded, offset);
|
||||
printf("Scrambling params: nushift %d M %d length %d offset %d\n", nushift, M, length, info.offset);
|
||||
#endif
|
||||
#ifdef DEBUG_PBCH_ENCODING
|
||||
printf("s: %04x\t", s);
|
||||
#endif
|
||||
int k = 0;
|
||||
|
||||
if (!encoded) {
|
||||
/// 1st Scrambling
|
||||
for (int i = 0; i < length; ++i) {
|
||||
if ((unscrambling_mask>>i)&1)
|
||||
pbch->pbch_a_prime ^= ((pbch->pbch_a_interleaved>>i)&1)<<i;
|
||||
else {
|
||||
if (((k + offset) & 0x1f) == 0)
|
||||
goldIdx++;
|
||||
pbch->pbch_a_prime ^= (((pbch->pbch_a_interleaved >> i) & 1) ^ ((s[goldIdx] >> ((k + offset) & 0x1f)) & 1)) << i;
|
||||
k++; /// k increase only when payload bit is not special bit
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/// 2nd Scrambling
|
||||
for (int i = 0; i < length; ++i) {
|
||||
if (((i + offset) & 0x1f) == 0)
|
||||
goldIdx++;
|
||||
pbch_e[i >> 5] ^= (((s[goldIdx] >> ((i + offset) & 0x1f)) & 1) << (i & 0x1f));
|
||||
}
|
||||
for (int i = 0; i < length; ++i) {
|
||||
if (((i + info.offset) & 0x1f) == 0)
|
||||
goldIdx++;
|
||||
pbch_e[i >> 5] ^= (((s[goldIdx] >> ((i + info.offset) & 0x1f)) & 1) << (i & 0x1f));
|
||||
}
|
||||
}
|
||||
|
||||
void nr_init_pbch_interleaver(uint8_t *interleaver) {
|
||||
uint8_t j_sfn=0, j_hrf=10, j_ssb=11, j_other=14;
|
||||
memset((void *)interleaver,0, NR_POLAR_PBCH_PAYLOAD_BITS);
|
||||
|
||||
for (uint8_t i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
|
||||
if (!i) // choice bit:1
|
||||
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_other++);
|
||||
else if (i<7) //Sfn bits:6
|
||||
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_sfn++);
|
||||
else if (i<24) // other:17
|
||||
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_other++);
|
||||
else if (i<28) // Sfn:4
|
||||
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_sfn++);
|
||||
else if (i==28) // Hrf bit:1
|
||||
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_hrf);
|
||||
else // Ssb bits:3
|
||||
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_ssb++);
|
||||
static uint32_t nr_pbch_scrambling(uint32_t pbch_a_interleaved,
|
||||
uint32_t Nid,
|
||||
uint8_t nushift,
|
||||
uint16_t M,
|
||||
uint16_t length,
|
||||
uint32_t unscrambling_mask)
|
||||
{
|
||||
uint32_t pbch_a_prime = 0;
|
||||
int k = 0;
|
||||
NR_PBCH_scramb_info_t info = get_scrambling_info(nushift, M, length);
|
||||
uint32_t *s = gold_cache(Nid, info.len);
|
||||
#ifdef DEBUG_PBCH_ENCODING
|
||||
printf("Scrambling params: nushift %d M %d length %d offset %d\n", nushift, M, length, info.offset);
|
||||
#endif
|
||||
#ifdef DEBUG_PBCH_ENCODING
|
||||
printf("s: %04x\t", s);
|
||||
#endif
|
||||
int goldIdx = info.goldIdx;
|
||||
for (int i = 0; i < length; ++i) {
|
||||
if ((unscrambling_mask >> i) & 1)
|
||||
pbch_a_prime ^= ((pbch_a_interleaved >> i) & 1) << i;
|
||||
else {
|
||||
if (((k + info.offset) & 0x1f) == 0)
|
||||
goldIdx++;
|
||||
pbch_a_prime ^= (((pbch_a_interleaved >> i) & 1) ^ ((s[goldIdx] >> ((k + info.offset) & 0x1f)) & 1)) << i;
|
||||
k++; /// k increase only when payload bit is not special bit
|
||||
}
|
||||
}
|
||||
return pbch_a_prime;
|
||||
}
|
||||
|
||||
int nr_generate_pbch(nfapi_nr_dl_tti_ssb_pdu *ssb_pdu,
|
||||
uint8_t *interleaver,
|
||||
c16_t *txdataF,
|
||||
int16_t amp,
|
||||
uint8_t ssb_start_symbol,
|
||||
uint8_t n_hf,
|
||||
int sfn,
|
||||
nfapi_nr_config_request_scf_t *config,
|
||||
NR_DL_FRAME_PARMS *frame_parms) {
|
||||
int k,l,m;
|
||||
//int16_t a;
|
||||
int16_t mod_pbch_e[NR_POLAR_PBCH_E];
|
||||
uint8_t idx=0;
|
||||
uint16_t M;
|
||||
uint8_t nushift;
|
||||
uint32_t unscrambling_mask;
|
||||
void nr_init_pbch_interleaver(uint8_t *interleaver)
|
||||
{
|
||||
uint8_t j_sfn = 0, j_hrf = 10, j_ssb = 11, j_other = 14;
|
||||
memset((void *)interleaver,0, NR_POLAR_PBCH_PAYLOAD_BITS);
|
||||
|
||||
for (int i = 0; i < NR_POLAR_PBCH_PAYLOAD_BITS; i++)
|
||||
if (!i) // choice bit:1
|
||||
*(interleaver + i) = *(nr_pbch_payload_interleaving_pattern + j_other++);
|
||||
else if (i < 7) //Sfn bits:6
|
||||
*(interleaver + i) = *(nr_pbch_payload_interleaving_pattern + j_sfn++);
|
||||
else if (i < 24) // other:17
|
||||
*(interleaver + i) = *(nr_pbch_payload_interleaving_pattern + j_other++);
|
||||
else if (i < 28) // Sfn:4
|
||||
*(interleaver + i) = *(nr_pbch_payload_interleaving_pattern + j_sfn++);
|
||||
else if (i == 28) // Hrf bit:1
|
||||
*(interleaver + i) = *(nr_pbch_payload_interleaving_pattern + j_hrf);
|
||||
else // Ssb bits:3
|
||||
*(interleaver + i) = *(nr_pbch_payload_interleaving_pattern + j_ssb++);
|
||||
}
|
||||
|
||||
uint32_t nr_pbch_extra_byte_generation(int sfn, int n_hf, int ssb_index, int ssb_sc_offset, int Lmax)
|
||||
{
|
||||
uint32_t extra_byte = 0;
|
||||
// Extra byte generation
|
||||
for (int i = 0; i < 4; i++)
|
||||
extra_byte |= ((sfn >> (3 - i)) & 1) << i; // resp. 4th, 3rd, 2nd ans 1st lsb of sfn
|
||||
|
||||
extra_byte |= n_hf << 4; // half frame index bit
|
||||
|
||||
if (Lmax == 64)
|
||||
for (int i = 0; i < 3; i++)
|
||||
extra_byte |= (uint32_t)((ssb_index >> (5 - i)) & 1) << (5 + i); // resp. 6th, 5th and 4th bits of ssb_index
|
||||
else
|
||||
extra_byte |= ((ssb_sc_offset >> 4) & 1) << 5; //MSB of k_SSB (bit index 4)
|
||||
return extra_byte;
|
||||
}
|
||||
|
||||
void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
const nfapi_nr_dl_tti_ssb_pdu *ssb_pdu,
|
||||
c16_t *txdataF,
|
||||
uint8_t ssb_start_symbol,
|
||||
uint8_t n_hf,
|
||||
int sfn,
|
||||
nfapi_nr_config_request_scf_t *config,
|
||||
NR_DL_FRAME_PARMS *frame_parms)
|
||||
{
|
||||
LOG_D(PHY, "PBCH generation started\n");
|
||||
///Payload generation
|
||||
NR_gNB_PBCH m_pbch;
|
||||
NR_gNB_PBCH *pbch = &m_pbch;
|
||||
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;
|
||||
const uint8_t *pbch_pdu = (const uint8_t*)&ssb_pdu->ssb_pdu_rel15.bchPayload;
|
||||
uint8_t Lmax = frame_parms->Lmax;
|
||||
for (int i=0; i<NR_PBCH_PDU_BITS; i++)
|
||||
pbch->pbch_a |= ((pbch_pdu[i>>3]>>(7-(i&7)))&1)<<i;
|
||||
uint32_t pbch_a = 0;
|
||||
for (int i = 0; i < NR_PBCH_PDU_BITS; i++)
|
||||
pbch_a |= ((pbch_pdu[i >> 3] >> (7 - (i & 7))) & 1) << i;
|
||||
|
||||
// NSA to signal no coreset0
|
||||
const int ssb_sc_offset = get_softmodem_params()->sa ? config->ssb_table.ssb_subcarrier_offset.value : 31;
|
||||
|
||||
#ifdef DEBUG_PBCH_ENCODING
|
||||
for (int i=0; i<3; i++)
|
||||
for (int i = 0; i < 3; i++)
|
||||
printf("pbch_pdu[%d]: 0x%02x\n", i, pbch_pdu[i]);
|
||||
|
||||
printf("PBCH payload = 0x%08x\n",pbch->pbch_a);
|
||||
printf("PBCH payload = 0x%08x\n", pbch_a);
|
||||
#endif
|
||||
|
||||
// Extra byte generation
|
||||
for (int i=0; i<4; i++)
|
||||
pbch->pbch_a |= ((sfn>>(3-i))&1)<<(24+i); // resp. 4th, 3rd, 2nd ans 1st lsb of sfn
|
||||
|
||||
pbch->pbch_a |= n_hf<<28; // half frame index bit
|
||||
|
||||
if (Lmax == 64)
|
||||
for (int i = 0; i < 3; i++)
|
||||
pbch->pbch_a |= (uint32_t)((ssb_index >> (5 - i)) & 1) << (29 + i); // resp. 6th, 5th and 4th bits of ssb_index
|
||||
else
|
||||
pbch->pbch_a |= ((ssb_sc_offset >> 4) & 1) << 29; //MSB of k_SSB (bit index 4)
|
||||
|
||||
LOG_D(PHY,"After extra byte: pbch_a = 0x%08x\n",pbch->pbch_a);
|
||||
uint32_t extra_byte = nr_pbch_extra_byte_generation(sfn, n_hf, ssb_index, ssb_sc_offset, Lmax);
|
||||
pbch_a |= extra_byte << 24;
|
||||
LOG_D(PHY,"After extra byte: pbch_a = 0x%08x\n", pbch_a);
|
||||
|
||||
// Payload interleaving
|
||||
|
||||
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++) {
|
||||
pbch->pbch_a_interleaved |= ((pbch->pbch_a>>i)&1)<<(*(interleaver+i));
|
||||
uint32_t pbch_a_interleaved = 0;
|
||||
uint8_t *interleaver = gNB->nr_pbch_interleaver;
|
||||
for (int i = 0; i < NR_POLAR_PBCH_PAYLOAD_BITS; i++) {
|
||||
pbch_a_interleaved |= ((pbch_a >> i) & 1) << (*(interleaver + i));
|
||||
#ifdef DEBUG_PBCH_ENCODING
|
||||
printf("i %d out 0x%08x ilv %d (in>>i)&1) %d\n", i, pbch->pbch_a_interleaved, *(interleaver+i), (pbch->pbch_a>>i)&1);
|
||||
printf("i %d out 0x%08x ilv %d (in>>i)&1) %d\n", i, pbch_a_interleaved, *(interleaver+i), (pbch_a >> i) & 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PBCH_ENCODING
|
||||
printf("Interleaving:\n");
|
||||
printf("pbch_a_interleaved: 0x%08x\n", pbch->pbch_a_interleaved);
|
||||
printf("pbch_a_interleaved: 0x%08x\n", pbch_a_interleaved);
|
||||
#endif
|
||||
// Scrambling
|
||||
unscrambling_mask = (Lmax ==64)? 0x100006D:0x1000041;
|
||||
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
|
||||
nushift = (((sfn>>2)&1)<<1) ^ ((sfn>>1)&1);
|
||||
pbch->pbch_a_prime = 0;
|
||||
nr_pbch_scrambling(pbch, (uint32_t)config->cell_config.phy_cell_id.value, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS, 0, unscrambling_mask);
|
||||
uint32_t unscrambling_mask = (Lmax == 64) ? 0x100006D : 0x1000041;
|
||||
uint16_t M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
|
||||
uint8_t nushift = (((sfn >> 2) & 1) << 1) ^ ((sfn >> 1) & 1);
|
||||
uint32_t pbch_a_prime = nr_pbch_scrambling(pbch_a_interleaved,
|
||||
(uint32_t)config->cell_config.phy_cell_id.value,
|
||||
nushift,
|
||||
M,
|
||||
NR_POLAR_PBCH_PAYLOAD_BITS,
|
||||
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);
|
||||
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_a_prime);
|
||||
#endif
|
||||
|
||||
// Encoder reversal
|
||||
uint64_t a_reversed = reverse_bits((uint64_t)pbch->pbch_a_prime, NR_POLAR_PBCH_PAYLOAD_BITS);
|
||||
|
||||
uint64_t a_reversed = reverse_bits((uint64_t)pbch_a_prime, NR_POLAR_PBCH_PAYLOAD_BITS);
|
||||
uint32_t pbch_e[NR_POLAR_PBCH_E_DWORD];
|
||||
/// CRC, coding and rate matching
|
||||
polar_encoder_fast (&a_reversed, (void*)pbch->pbch_e, 0, 0,
|
||||
NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL);
|
||||
polar_encoder_fast(&a_reversed,
|
||||
pbch_e,
|
||||
0,
|
||||
0,
|
||||
NR_POLAR_PBCH_MESSAGE_TYPE,
|
||||
NR_POLAR_PBCH_PAYLOAD_BITS,
|
||||
NR_POLAR_PBCH_AGGREGATION_LEVEL);
|
||||
|
||||
#ifdef DEBUG_PBCH_ENCODING
|
||||
printf("Channel coding:\n");
|
||||
|
||||
for (int i=0; i<NR_POLAR_PBCH_E_DWORD; i++)
|
||||
printf("pbch_e[%d]: 0x%08x\t", i, pbch->pbch_e[i]);
|
||||
|
||||
for (int i = 0; i < NR_POLAR_PBCH_E_DWORD; i++)
|
||||
printf("pbch_e[%d]: 0x%08x\t", i, pbch_e[i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
/// Scrambling
|
||||
M = NR_POLAR_PBCH_E;
|
||||
nushift = (Lmax==4)? ssb_index&3 : ssb_index&7;
|
||||
nr_pbch_scrambling(pbch, (uint32_t)config->cell_config.phy_cell_id.value, nushift, M, NR_POLAR_PBCH_E, 1, 0);
|
||||
M = NR_POLAR_PBCH_E;
|
||||
nushift = (Lmax == 4) ? ssb_index & 3 : ssb_index & 7;
|
||||
nr_pbch_encoded_scrambling(pbch_e,
|
||||
(uint32_t)config->cell_config.phy_cell_id.value,
|
||||
nushift,
|
||||
M,
|
||||
NR_POLAR_PBCH_E);
|
||||
#ifdef DEBUG_PBCH_ENCODING
|
||||
printf("Scrambling:\n");
|
||||
|
||||
for (int i=0; i<NR_POLAR_PBCH_E_DWORD; i++)
|
||||
printf("pbch_e[%d]: 0x%08x\t", i, pbch->pbch_e[i]);
|
||||
for (int i = 0; i < NR_POLAR_PBCH_E_DWORD; i++)
|
||||
printf("pbch_e[%d]: 0x%08x\t", i, pbch_e[i]);
|
||||
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
int16_t mod_pbch_e[NR_POLAR_PBCH_E];
|
||||
/// QPSK modulation
|
||||
for (int i=0; i<NR_POLAR_PBCH_E>>1; i++) {
|
||||
idx = ((pbch->pbch_e[(i<<1)>>5]>>((i<<1)&0x1f))&3);
|
||||
mod_pbch_e[i<<1] = nr_qpsk_mod_table[idx<<1];
|
||||
mod_pbch_e[(i<<1)+1] = nr_qpsk_mod_table[(idx<<1)+1];
|
||||
int idx = ((pbch_e[(i << 1) >> 5] >> ((i << 1) & 0x1f)) & 3);
|
||||
mod_pbch_e[i<<1] = nr_qpsk_mod_table[idx << 1];
|
||||
mod_pbch_e[(i<<1)+1] = nr_qpsk_mod_table[(idx << 1) + 1];
|
||||
#ifdef DEBUG_PBCH
|
||||
printf("i %d idx %d mod_pbch %d %d\n", i, idx, mod_pbch_e[2*i], mod_pbch_e[2*i+1]);
|
||||
printf("i %d idx %d mod_pbch %d %d\n", i, idx, mod_pbch_e[2 * i], mod_pbch_e[2 * i + 1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -326,9 +361,10 @@ int nr_generate_pbch(nfapi_nr_dl_tti_ssb_pdu *ssb_pdu,
|
||||
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;
|
||||
l = ssb_start_symbol + 1;
|
||||
m = 0;
|
||||
int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
|
||||
int l = ssb_start_symbol + 1;
|
||||
int m = 0;
|
||||
int16_t amp = gNB->TX_AMP;
|
||||
|
||||
for (int ssb_sc_idx = 0; ssb_sc_idx < 240; ssb_sc_idx++) {
|
||||
if ((ssb_sc_idx&3) == nushift) { //skip DMRS
|
||||
@@ -419,7 +455,4 @@ int nr_generate_pbch(nfapi_nr_dl_tti_ssb_pdu *ssb_pdu,
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -432,21 +432,17 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
uint16_t *max_preamble_energy,
|
||||
uint16_t *max_preamble_delay)
|
||||
{
|
||||
AssertFatal(gNB!=NULL,"Can only be called from gNB\n");
|
||||
|
||||
int i;
|
||||
|
||||
nfapi_nr_prach_config_t *cfg=&gNB->gNB_config.prach_config;
|
||||
AssertFatal(gNB != NULL, "Can only be called from gNB\n");
|
||||
nfapi_nr_prach_config_t *cfg = &gNB->gNB_config.prach_config;
|
||||
NR_DL_FRAME_PARMS *fp;
|
||||
|
||||
uint16_t rootSequenceIndex;
|
||||
int numrootSequenceIndex;
|
||||
uint8_t restricted_set;
|
||||
uint8_t n_ra_prb=0xFF;
|
||||
int16_t *prachF=NULL;
|
||||
int nb_rx;
|
||||
uint16_t rootSequenceIndex;
|
||||
int numrootSequenceIndex;
|
||||
uint8_t restricted_set;
|
||||
uint8_t n_ra_prb=0xFF;
|
||||
int nb_rx;
|
||||
|
||||
int16_t **rxsigF = gNB->prach_vars.rxsigF;
|
||||
int16_t **rxsigF = gNB->prach_vars.rxsigF;
|
||||
|
||||
uint8_t preamble_index;
|
||||
uint16_t NCS=99,NCS2;
|
||||
@@ -460,10 +456,8 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
uint8_t not_found;
|
||||
uint16_t u;
|
||||
int16_t *Xu=0;
|
||||
uint16_t offset;
|
||||
uint16_t first_nonzero_root_idx=0;
|
||||
uint8_t new_dft=0;
|
||||
uint8_t aa;
|
||||
int32_t lev;
|
||||
int16_t levdB;
|
||||
int log2_ifft_size=10;
|
||||
@@ -473,23 +467,22 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
fp = &gNB->frame_parms;
|
||||
|
||||
nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value;
|
||||
rootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].prach_root_sequence_index.value;
|
||||
numrootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].num_root_sequences.value;
|
||||
NCS = prach_pdu->num_cs;//cfg->num_prach_fd_occasions_list[0].prach_zero_corr_conf.value;
|
||||
rootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].prach_root_sequence_index.value;
|
||||
numrootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].num_root_sequences.value;
|
||||
NCS = prach_pdu->num_cs;//cfg->num_prach_fd_occasions_list[0].prach_zero_corr_conf.value;
|
||||
int prach_sequence_length = cfg->prach_sequence_length.value;
|
||||
int msg1_frequencystart = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].k1.value;
|
||||
int msg1_frequencystart = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].k1.value;
|
||||
// int num_unused_root_sequences = cfg->num_prach_fd_occasions_list[0].num_unused_root_sequences.value;
|
||||
// cfg->num_prach_fd_occasions_list[0].unused_root_sequences_list
|
||||
|
||||
restricted_set = cfg->restricted_set_config.value;
|
||||
restricted_set = cfg->restricted_set_config.value;
|
||||
|
||||
uint8_t prach_fmt = prach_pdu->prach_format;
|
||||
uint16_t N_ZC = (prach_sequence_length==0)?839:139;
|
||||
|
||||
LOG_D(PHY,"L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d, format %d \n",rootSequenceIndex,numrootSequenceIndex,NCS,N_ZC,prach_fmt);
|
||||
|
||||
prach_ifft = gNB->prach_vars.prach_ifft;
|
||||
prachF = gNB->prach_vars.prachF;
|
||||
prach_ifft = gNB->prach_vars.prach_ifft;
|
||||
if (LOG_DEBUGFLAG(PRACH)){
|
||||
if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for slot %d, msg1_frequencystart %d, rootSequenceIndex %d\n", slot, msg1_frequencystart, rootSequenceIndex);
|
||||
}
|
||||
@@ -508,10 +501,10 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
preamble_offset_old = 99;
|
||||
|
||||
|
||||
*max_preamble_energy=0;
|
||||
*max_preamble_delay=0;
|
||||
*max_preamble=0;
|
||||
|
||||
*max_preamble_energy = 0;
|
||||
*max_preamble_delay = 0;
|
||||
*max_preamble = 0;
|
||||
int16_t prachF[2 * 1024];
|
||||
for (preamble_index=0 ; preamble_index<64 ; preamble_index++) {
|
||||
|
||||
if (LOG_DEBUGFLAG(PRACH)){
|
||||
@@ -521,14 +514,14 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
if (restricted_set == 0) {
|
||||
// This is the relative offset in the root sequence table (5.7.2-4 from 36.211) for the given preamble index
|
||||
preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS)));
|
||||
|
||||
|
||||
if (preamble_offset != preamble_offset_old) {
|
||||
preamble_offset_old = preamble_offset;
|
||||
new_dft = 1;
|
||||
// This is the \nu corresponding to the preamble index
|
||||
preamble_shift = 0;
|
||||
}
|
||||
|
||||
|
||||
else {
|
||||
preamble_shift -= NCS;
|
||||
|
||||
@@ -551,33 +544,32 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
// current root depending on rootSequenceIndex
|
||||
int index = (rootSequenceIndex + preamble_offset) % N_ZC;
|
||||
|
||||
u = prach_root_sequence_map[index];
|
||||
u = prach_root_sequence_map[index];
|
||||
|
||||
uint16_t n_group_ra = 0;
|
||||
uint16_t n_group_ra = 0;
|
||||
|
||||
if ( (nr_du[u]<(N_ZC/3)) && (nr_du[u]>=NCS) ) {
|
||||
n_shift_ra = nr_du[u]/NCS;
|
||||
d_start = (nr_du[u]<<1) + (n_shift_ra * NCS);
|
||||
n_group_ra = N_ZC/d_start;
|
||||
n_shift_ra_bar = max(0,(N_ZC-(nr_du[u]<<1)-(n_group_ra*d_start))/N_ZC);
|
||||
} else if ( (nr_du[u]>=(N_ZC/3)) && (nr_du[u]<=((N_ZC - NCS)>>1)) ) {
|
||||
n_shift_ra = (N_ZC - (nr_du[u]<<1))/NCS;
|
||||
d_start = N_ZC - (nr_du[u]<<1) + (n_shift_ra * NCS);
|
||||
n_group_ra = nr_du[u]/d_start;
|
||||
n_shift_ra_bar = min(n_shift_ra,max(0,(nr_du[u]- (n_group_ra*d_start))/NCS));
|
||||
} else {
|
||||
n_shift_ra = 0;
|
||||
n_shift_ra_bar = 0;
|
||||
}
|
||||
|
||||
// This is the number of cyclic shifts for the current root u
|
||||
numshift = (n_shift_ra*n_group_ra) + n_shift_ra_bar;
|
||||
// skip to next root and recompute parameters if numshift==0
|
||||
(numshift>0) ? (not_found = 0) : (preamble_offset++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((nr_du[u] < (N_ZC / 3)) && (nr_du[u] >= NCS) ) {
|
||||
n_shift_ra = nr_du[u] / NCS;
|
||||
d_start = (nr_du[u] << 1) + (n_shift_ra * NCS);
|
||||
n_group_ra = N_ZC / d_start;
|
||||
n_shift_ra_bar = max(0, (N_ZC-(nr_du[u] << 1) - (n_group_ra * d_start)) / N_ZC);
|
||||
} else if ((nr_du[u] >= (N_ZC / 3)) && (nr_du[u] <= ((N_ZC - NCS) >> 1))) {
|
||||
n_shift_ra = (N_ZC - (nr_du[u] << 1)) / NCS;
|
||||
d_start = N_ZC - (nr_du[u] << 1) + (n_shift_ra * NCS);
|
||||
n_group_ra = nr_du[u] / d_start;
|
||||
n_shift_ra_bar = min(n_shift_ra, max(0, (nr_du[u]- (n_group_ra * d_start)) / NCS));
|
||||
} else {
|
||||
n_shift_ra = 0;
|
||||
n_shift_ra_bar = 0;
|
||||
}
|
||||
|
||||
// This is the number of cyclic shifts for the current root u
|
||||
numshift = (n_shift_ra * n_group_ra) + n_shift_ra_bar;
|
||||
// skip to next root and recompute parameters if numshift==0
|
||||
(numshift>0) ? (not_found = 0) : (preamble_offset++);
|
||||
}
|
||||
}
|
||||
|
||||
if (n_shift_ra>0)
|
||||
preamble_shift = -((d_start * (preamble_index0/n_shift_ra)) + ((preamble_index0%n_shift_ra)*NCS)); // minus because the channel is h(t -\tau + Cv)
|
||||
else
|
||||
@@ -595,8 +587,17 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
// Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex
|
||||
if (LOG_DEBUGFLAG(PRACH)) {
|
||||
int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840));
|
||||
if (en>60) LOG_D(PHY,"frame %d, slot %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n",
|
||||
frame,slot,preamble_index,NCS,N_ZC/NCS,preamble_offset,preamble_shift,en);
|
||||
if (en>60)
|
||||
LOG_D(PHY,
|
||||
"frame %d, slot %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n",
|
||||
frame,
|
||||
slot,
|
||||
preamble_index,
|
||||
NCS,
|
||||
N_ZC / NCS,
|
||||
preamble_offset,
|
||||
preamble_shift,
|
||||
en);
|
||||
}
|
||||
|
||||
LOG_D(PHY,"PRACH RX preamble_index %d, preamble_offset %d\n",preamble_index,preamble_offset);
|
||||
@@ -605,57 +606,56 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
if (new_dft == 1) {
|
||||
new_dft = 0;
|
||||
|
||||
Xu=(int16_t*)gNB->X_u[preamble_offset-first_nonzero_root_idx];
|
||||
Xu = (int16_t*)gNB->X_u[preamble_offset-first_nonzero_root_idx];
|
||||
|
||||
LOG_D(PHY,"PRACH RX new dft preamble_offset-first_nonzero_root_idx %d\n",preamble_offset-first_nonzero_root_idx);
|
||||
|
||||
|
||||
memset(prach_ifft,0,((N_ZC==839) ? 2048 : 256)*sizeof(int32_t));
|
||||
|
||||
|
||||
memset(prachF, 0, sizeof(int16_t)*2*1024 );
|
||||
if (LOG_DUMPFLAG(PRACH)) {
|
||||
memset(prachF, 0, sizeof(int16_t) * 2 * 1024);
|
||||
if (LOG_DUMPFLAG(PRACH)) {
|
||||
LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],N_ZC,1,1);
|
||||
LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1);
|
||||
}
|
||||
|
||||
for (aa=0;aa<nb_rx; aa++) {
|
||||
for (int aa = 0; aa < nb_rx; aa++) {
|
||||
// Do componentwise product with Xu* on each antenna
|
||||
|
||||
for (offset=0; offset<(N_ZC<<1); offset+=2) {
|
||||
prachF[offset] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset] + (int32_t)Xu[offset+1]*rxsigF[aa][offset+1])>>15);
|
||||
prachF[offset+1] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset+1] - (int32_t)Xu[offset+1]*rxsigF[aa][offset])>>15);
|
||||
}
|
||||
for (int offset = 0; offset < (N_ZC << 1); offset += 2) {
|
||||
prachF[offset] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset] + (int32_t)Xu[offset+1]*rxsigF[aa][offset+1])>>15);
|
||||
prachF[offset+1] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset+1] - (int32_t)Xu[offset+1]*rxsigF[aa][offset])>>15);
|
||||
}
|
||||
|
||||
// Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139)
|
||||
if (N_ZC == 839) {
|
||||
idft(IDFT_1024,prachF,prach_ifft_tmp,1);
|
||||
// compute energy and accumulate over receive antennas
|
||||
for (i=0;i<1024;i++)
|
||||
prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)];
|
||||
} else {
|
||||
idft(IDFT_256,prachF,prach_ifft_tmp,1);
|
||||
log2_ifft_size = 8;
|
||||
// compute energy and accumulate over receive antennas and repetitions for BR
|
||||
for (i=0;i<256;i++)
|
||||
prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)];
|
||||
}
|
||||
|
||||
if (LOG_DUMPFLAG(PRACH)) {
|
||||
if (aa==0) LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
|
||||
if (aa==1) LOG_M("prach_rxF_comp1.m","prach_rxF_comp1",prachF,1024,1,1);
|
||||
// Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139)
|
||||
if (N_ZC == 839) {
|
||||
idft(IDFT_1024, prachF, prach_ifft_tmp, 1);
|
||||
// compute energy and accumulate over receive antennas
|
||||
for (int i = 0; i < 1024; i++)
|
||||
prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)];
|
||||
} else {
|
||||
idft(IDFT_256, prachF, prach_ifft_tmp, 1);
|
||||
log2_ifft_size = 8;
|
||||
// compute energy and accumulate over receive antennas and repetitions for BR
|
||||
for (int i = 0; i < 256; i++)
|
||||
prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)];
|
||||
}
|
||||
|
||||
}// antennas_rx
|
||||
if (LOG_DUMPFLAG(PRACH)) {
|
||||
if (aa == 0)
|
||||
LOG_M("prach_rxF_comp0.m","prach_rxF_comp0", prachF, 1024, 1, 1);
|
||||
if (aa == 1)
|
||||
LOG_M("prach_rxF_comp1.m","prach_rxF_comp1", prachF, 1024, 1, 1);
|
||||
}
|
||||
|
||||
} // antennas_rx
|
||||
|
||||
// Normalization of energy over ifft and receive antennas
|
||||
if (N_ZC == 839) {
|
||||
log2_ifft_size = 10;
|
||||
for (i=0;i<1024;i++)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
prach_ifft[i] = (prach_ifft[i]>>log2_ifft_size)/nb_rx;
|
||||
} else {
|
||||
log2_ifft_size = 8;
|
||||
for (i=0;i<256;i++)
|
||||
for (int i = 0; i < 256; i++)
|
||||
prach_ifft[i] = (prach_ifft[i]>>log2_ifft_size)/nb_rx;
|
||||
}
|
||||
|
||||
@@ -665,14 +665,14 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
|
||||
preamble_shift2 = ((preamble_shift==0) ? 0 : ((preamble_shift<<log2_ifft_size)/N_ZC));
|
||||
|
||||
for (i=0; i<NCS2; i++) {
|
||||
for (int i = 0; i < NCS2; i++) {
|
||||
lev = (int32_t)prach_ifft[(preamble_shift2+i)];
|
||||
levdB = dB_fixed_times10(lev);
|
||||
if (levdB>*max_preamble_energy) {
|
||||
LOG_D(PHY,"preamble_index %d, delay %d en %d dB > %d dB\n",preamble_index,i,levdB,*max_preamble_energy);
|
||||
*max_preamble_energy = levdB;
|
||||
*max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate
|
||||
*max_preamble = preamble_index;
|
||||
*max_preamble_energy = levdB;
|
||||
*max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate
|
||||
*max_preamble = preamble_index;
|
||||
}
|
||||
}
|
||||
}// preamble_index
|
||||
@@ -695,9 +695,11 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
// max_preamble_delay * ( (2048/2^mu*(fs/30.72M)) / 256 ) / fs = TA * 16 * 64 / 2^mu * Tc
|
||||
uint16_t *TA = max_preamble_delay;
|
||||
int mu = fp->numerology_index;
|
||||
if (cfg->prach_sequence_length.value==0) {
|
||||
if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) *TA = *TA*3*(1<<mu)/2;
|
||||
else if (prach_fmt == 3) *TA = *TA*3*(1<<mu)/8;
|
||||
if (cfg->prach_sequence_length.value == 0) {
|
||||
if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2)
|
||||
*TA = *TA * 3 * (1 << mu) / 2;
|
||||
else if (prach_fmt == 3)
|
||||
*TA = *TA * 3 * (1 << mu) / 8;
|
||||
}
|
||||
else *TA = *TA/2;
|
||||
|
||||
@@ -705,19 +707,18 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
if (LOG_DUMPFLAG(PRACH)) {
|
||||
//int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840));
|
||||
// if (en>60) {
|
||||
int k = (12*n_ra_prb) - 6*fp->N_RB_UL;
|
||||
|
||||
if (k<0) k+=fp->ofdm_symbol_size;
|
||||
|
||||
int k = (12 * n_ra_prb) - 6 * fp->N_RB_UL;
|
||||
if (k < 0)
|
||||
k += fp->ofdm_symbol_size;
|
||||
|
||||
k*=12;
|
||||
k+=13;
|
||||
k*=2;
|
||||
|
||||
|
||||
LOG_M("rxsigF.m","prach_rxF",&rxsigF[0][0],12288,1,1);
|
||||
LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
|
||||
LOG_M("Xu.m","xu",Xu,N_ZC,1,1);
|
||||
LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1);
|
||||
LOG_M("rxsigF.m","prach_rxF", &rxsigF[0][0], 12288, 1, 1);
|
||||
LOG_M("prach_rxF_comp0.m","prach_rxF_comp0", prachF, 1024, 1, 1);
|
||||
LOG_M("Xu.m","xu", Xu, N_ZC, 1, 1);
|
||||
LOG_M("prach_ifft0.m","prach_t0", prach_ifft, 1024, 1, 1);
|
||||
// }
|
||||
} /* LOG_DUMPFLAG(PRACH) */
|
||||
stop_meas(&gNB->rx_prach);
|
||||
|
||||
@@ -72,33 +72,30 @@ int nr_generate_sss(c16_t *txdataF,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
/*!
|
||||
\fn int nr_generate_pbch_dmrs
|
||||
\fn void nr_generate_pbch_dmrs
|
||||
\brief Generation of the DMRS for the PBCH
|
||||
@param
|
||||
@returns 0 on success
|
||||
*/
|
||||
int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
c16_t *txdataF,
|
||||
int16_t amp,
|
||||
uint8_t ssb_start_symbol,
|
||||
nfapi_nr_config_request_scf_t *config,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
c16_t *txdataF,
|
||||
int16_t amp,
|
||||
uint8_t ssb_start_symbol,
|
||||
nfapi_nr_config_request_scf_t *config,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
/*!
|
||||
\fn int nr_generate_pbch
|
||||
\fn void nr_generate_pbch
|
||||
\brief Generation of the PBCH
|
||||
@param
|
||||
@returns 0 on success
|
||||
*/
|
||||
int nr_generate_pbch(nfapi_nr_dl_tti_ssb_pdu *ssb_pdu,
|
||||
uint8_t *interleaver,
|
||||
c16_t *txdataF,
|
||||
int16_t amp,
|
||||
uint8_t ssb_start_symbol,
|
||||
uint8_t n_hf,
|
||||
int sfn,
|
||||
nfapi_nr_config_request_scf_t *config,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
const nfapi_nr_dl_tti_ssb_pdu *ssb_pdu,
|
||||
c16_t *txdataF,
|
||||
uint8_t ssb_start_symbol,
|
||||
uint8_t n_hf,
|
||||
int sfn,
|
||||
nfapi_nr_config_request_scf_t *config,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
/*!
|
||||
\fn int nr_generate_pbch
|
||||
@@ -107,6 +104,7 @@ int nr_generate_pbch(nfapi_nr_dl_tti_ssb_pdu *ssb_pdu,
|
||||
@returns the bit index of the output
|
||||
*/
|
||||
void nr_init_pbch_interleaver(uint8_t *interleaver);
|
||||
uint32_t nr_pbch_extra_byte_generation(int sfn, int n_hf, int ssb_index, int ssb_sc_offset, int Lmax);
|
||||
|
||||
NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB);
|
||||
|
||||
|
||||
@@ -288,14 +288,11 @@ static void nr_ulsch_extract_rbs(c16_t* const rxdataF,
|
||||
NR_DL_FRAME_PARMS *frame_parms)
|
||||
{
|
||||
uint8_t delta = 0;
|
||||
|
||||
int start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start + pusch_pdu->bwp_start) * NR_NB_SC_PER_RB)%frame_parms->ofdm_symbol_size;
|
||||
int nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size;
|
||||
|
||||
|
||||
c16_t *rxF = &rxdataF[rxoffset];
|
||||
c16_t *rxF_ext = &rxFext[0];
|
||||
c16_t *ul_ch0 = &chF[choffset];
|
||||
c16_t *rxF = &rxdataF[rxoffset];
|
||||
c16_t *rxF_ext = &rxFext[0];
|
||||
c16_t *ul_ch0 = &chF[choffset];
|
||||
c16_t *ul_ch0_ext = &chFext[0];
|
||||
|
||||
if (is_dmrs_symbol == 0) {
|
||||
@@ -307,11 +304,11 @@ static void nr_ulsch_extract_rbs(c16_t* const rxdataF,
|
||||
memcpy(rxF_ext, &rxF[start_re], neg_length * sizeof(c16_t));
|
||||
memcpy(&rxF_ext[neg_length], rxF, pos_length * sizeof(c16_t));
|
||||
}
|
||||
memcpy(ul_ch0_ext, ul_ch0, nb_re_pusch * sizeof(c16_t));
|
||||
memcpy(ul_ch0_ext, ul_ch0, nb_re_pusch * sizeof(c16_t));
|
||||
}
|
||||
else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1) { // 6 REs / PRB
|
||||
AssertFatal(delta == 0 || delta == 1, "Illegal delta %d\n",delta);
|
||||
c16_t *rxF32 = &rxF[start_re];
|
||||
c16_t *rxF32 = &rxF[start_re];
|
||||
if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) {
|
||||
for (int idx = 1 - delta; idx < nb_re_pusch; idx += 2) {
|
||||
*rxF_ext++ = rxF32[idx];
|
||||
@@ -367,7 +364,8 @@ static void nr_ulsch_extract_rbs(c16_t* const rxdataF,
|
||||
}
|
||||
}
|
||||
|
||||
static void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
|
||||
static void nr_ulsch_scale_channel(int size_est,
|
||||
int ul_ch_estimates_ext[][size_est],
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint8_t symbol,
|
||||
uint8_t is_dmrs_symbol,
|
||||
@@ -419,7 +417,8 @@ static int get_nb_re_pusch (NR_DL_FRAME_PARMS *frame_parms, nfapi_nr_pusch_pdu_t
|
||||
}
|
||||
|
||||
// compute average channel_level on each (TX,RX) antenna pair
|
||||
static void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
|
||||
static void nr_ulsch_channel_level(int size_est,
|
||||
int ul_ch_estimates_ext[][size_est],
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t *avg,
|
||||
uint8_t symbol,
|
||||
@@ -436,7 +435,7 @@ static void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
|
||||
//clear average level
|
||||
avg128U = simde_mm_setzero_si128();
|
||||
|
||||
ul_ch128 = (simde__m128i *)&ul_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx+aarx][symbol * len];
|
||||
ul_ch128 = (simde__m128i *)&ul_ch_estimates_ext[aatx * frame_parms->nb_antennas_rx + aarx][symbol * len];
|
||||
|
||||
for (int i = 0; i < len >> 2; i++) {
|
||||
avg128U = simde_mm_add_epi32(avg128U, simde_mm_srai_epi32(simde_mm_madd_epi16(ul_ch128[i], ul_ch128[i]), x));
|
||||
@@ -1445,6 +1444,28 @@ static void nr_pusch_symbol_processing(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t average_u32(const uint32_t *x, uint16_t size)
|
||||
{
|
||||
AssertFatal(size > 0 && x != NULL, "x is NULL or size is 0\n");
|
||||
|
||||
uint64_t sum_x = 0;
|
||||
simde__m256i vec_sum = simde_mm256_setzero_si256();
|
||||
|
||||
int i = 0;
|
||||
for (; i + 8 <= size; i += 8) {
|
||||
simde__m256i vec_data = simde_mm256_loadu_si256((simde__m256i *)&x[i]);
|
||||
vec_sum = simde_mm256_add_epi32(vec_sum, vec_data);
|
||||
}
|
||||
uint32_t *vec_sum32 = (uint32_t *)&vec_sum;
|
||||
for (int k = 0; k < 8; k++) {
|
||||
sum_x += vec_sum32[k];
|
||||
}
|
||||
for (; i < size; i++) {
|
||||
sum_x += x[i];
|
||||
}
|
||||
|
||||
return (uint32_t)(sum_x / size);
|
||||
}
|
||||
|
||||
int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
uint8_t ulsch_id,
|
||||
@@ -1505,14 +1526,38 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
pusch_vars->ulsch_power[aarx] = 0;
|
||||
pusch_vars->ulsch_noise_power[aarx] = 0;
|
||||
}
|
||||
for (int aatx = 0; aatx < rel15_ul->nrOfLayers; aatx++) {
|
||||
pusch_vars->ulsch_power[aarx] += signal_energy_nodc(
|
||||
(c16_t*)&pusch_vars->ul_ch_estimates[aatx * gNB->frame_parms.nb_antennas_rx + aarx][symbol * frame_parms->ofdm_symbol_size],
|
||||
rel15_ul->rb_size * 12);
|
||||
|
||||
int64_t symb_energy = 0;
|
||||
int start_sc = (rel15_ul->bwp_start + rel15_ul->rb_start) * NR_NB_SC_PER_RB;
|
||||
int middle_sc = frame_parms->ofdm_symbol_size - frame_parms->first_carrier_offset;
|
||||
int end_sc = (start_sc + rel15_ul->rb_size * NR_NB_SC_PER_RB - 1) % frame_parms->ofdm_symbol_size;
|
||||
|
||||
for (int s = rel15_ul->start_symbol_index; s < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); s++) {
|
||||
int offset0 = ((slot & 3) * frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size;
|
||||
int offset = offset0 + (frame_parms->first_carrier_offset + start_sc) % frame_parms->ofdm_symbol_size;
|
||||
c16_t *ul_ch = &gNB->common_vars.rxdataF[aarx][offset];
|
||||
if (end_sc < start_sc) {
|
||||
int64_t symb_energy_aux = signal_energy_nodc(ul_ch, middle_sc - start_sc) * (middle_sc - start_sc);
|
||||
ul_ch = &gNB->common_vars.rxdataF[aarx][offset0];
|
||||
symb_energy_aux += (signal_energy_nodc(ul_ch, end_sc + 1) * (end_sc + 1));
|
||||
symb_energy += symb_energy_aux / (rel15_ul->rb_size * NR_NB_SC_PER_RB);
|
||||
} else {
|
||||
symb_energy += signal_energy_nodc(ul_ch, rel15_ul->rb_size * NR_NB_SC_PER_RB);
|
||||
}
|
||||
}
|
||||
for (int rb = 0; rb < rel15_ul->rb_size; rb++)
|
||||
pusch_vars->ulsch_noise_power[aarx] +=
|
||||
n0_subband_power[aarx][rel15_ul->bwp_start + rel15_ul->rb_start + rb] / rel15_ul->rb_size;
|
||||
pusch_vars->ulsch_power[aarx] += (symb_energy / rel15_ul->nr_of_symbols);
|
||||
|
||||
pusch_vars->ulsch_noise_power[aarx] +=
|
||||
average_u32(&n0_subband_power[aarx][rel15_ul->bwp_start + rel15_ul->rb_start], rel15_ul->rb_size);
|
||||
|
||||
LOG_D(PHY,
|
||||
"aa %d, bwp_start%d, rb_start %d, rb_size %d: ulsch_power %d, ulsch_noise_power %d\n",
|
||||
aarx,
|
||||
rel15_ul->bwp_start,
|
||||
rel15_ul->rb_start,
|
||||
rel15_ul->rb_size,
|
||||
pusch_vars->ulsch_power[aarx],
|
||||
pusch_vars->ulsch_noise_power[aarx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1592,17 +1637,21 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
dmrs_symbol = get_valid_dmrs_idx_for_channel_est(rel15_ul->ul_dmrs_symb_pos, meas_symbol);
|
||||
else // average of channel estimates stored in first symbol
|
||||
dmrs_symbol = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, rel15_ul->start_symbol_index, end_symbol);
|
||||
|
||||
int size_est = nb_re_pusch * frame_parms->symbols_per_slot;
|
||||
__attribute__((aligned(32))) int ul_ch_estimates_ext[rel15_ul->nrOfLayers * frame_parms->nb_antennas_rx][size_est];
|
||||
memset(ul_ch_estimates_ext, 0, sizeof(ul_ch_estimates_ext));
|
||||
int buffer_length = rel15_ul->rb_size * NR_NB_SC_PER_RB;
|
||||
c16_t temp_rxFext[frame_parms->nb_antennas_rx][buffer_length] __attribute__((aligned(32)));
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
|
||||
for (int aatx = 0; aatx < rel15_ul->nrOfLayers; aatx++)
|
||||
for (int nl = 0; nl < rel15_ul->nrOfLayers; nl++)
|
||||
nr_ulsch_extract_rbs(gNB->common_vars.rxdataF[aarx],
|
||||
(c16_t*)pusch_vars->ul_ch_estimates[aatx * frame_parms->nb_antennas_rx + aarx],
|
||||
(c16_t*)&pusch_vars->rxdataF_ext[aarx][meas_symbol * nb_re_pusch],
|
||||
(c16_t*)&pusch_vars->ul_ch_estimates_ext[aatx * frame_parms->nb_antennas_rx+aarx][meas_symbol * nb_re_pusch],
|
||||
(c16_t *)pusch_vars->ul_ch_estimates[nl * frame_parms->nb_antennas_rx + aarx],
|
||||
temp_rxFext[aarx],
|
||||
(c16_t*)&ul_ch_estimates_ext[nl * frame_parms->nb_antennas_rx + aarx][meas_symbol * nb_re_pusch],
|
||||
soffset + meas_symbol * frame_parms->ofdm_symbol_size,
|
||||
dmrs_symbol * frame_parms->ofdm_symbol_size,
|
||||
aarx,
|
||||
(rel15_ul->ul_dmrs_symb_pos >> meas_symbol) & 0x01,
|
||||
(rel15_ul->ul_dmrs_symb_pos >> meas_symbol) & 0x01,
|
||||
rel15_ul,
|
||||
frame_parms);
|
||||
|
||||
@@ -1613,7 +1662,8 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
//----------------------------------------------------------
|
||||
//--------------------- Channel Scaling --------------------
|
||||
//----------------------------------------------------------
|
||||
nr_ulsch_scale_channel(pusch_vars->ul_ch_estimates_ext,
|
||||
nr_ulsch_scale_channel(size_est,
|
||||
ul_ch_estimates_ext,
|
||||
frame_parms,
|
||||
meas_symbol,
|
||||
(rel15_ul->ul_dmrs_symb_pos >> meas_symbol) & 0x01,
|
||||
@@ -1622,16 +1672,17 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
rel15_ul->rb_size,
|
||||
shift_ch_ext);
|
||||
|
||||
nr_ulsch_channel_level(pusch_vars->ul_ch_estimates_ext,
|
||||
nr_ulsch_channel_level(size_est,
|
||||
ul_ch_estimates_ext,
|
||||
frame_parms,
|
||||
avg,
|
||||
meas_symbol, // index of the start symbol
|
||||
nb_re_pusch, // number of the re in pusch
|
||||
rel15_ul->nrOfLayers);
|
||||
|
||||
for (int aatx = 0; aatx < rel15_ul->nrOfLayers; aatx++)
|
||||
for (int nl = 0; nl < rel15_ul->nrOfLayers; nl++)
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
|
||||
avgs = cmax(avgs, avg[aatx*frame_parms->nb_antennas_rx+aarx]);
|
||||
avgs = cmax(avgs, avg[nl * frame_parms->nb_antennas_rx + aarx]);
|
||||
|
||||
pusch_vars->log2_maxh = (log2_approx(avgs) >> 1);
|
||||
|
||||
|
||||
@@ -56,18 +56,9 @@ void exit_function(const char *file, const char *function, const int line, const
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include "openair1/PHY/TOOLS/phy_test_tools.hpp"
|
||||
#include <random>
|
||||
|
||||
constexpr bool is_power_of_two(uint64_t n)
|
||||
{
|
||||
return n > 0 && (n & (n - 1)) == 0;
|
||||
}
|
||||
|
||||
size_t align_up(size_t a, size_t b)
|
||||
{
|
||||
return (a + b - 1) / b * b;
|
||||
}
|
||||
|
||||
int16_t saturating_sub(int16_t a, int16_t b)
|
||||
{
|
||||
int32_t result = (int32_t)a - (int32_t)b;
|
||||
@@ -81,44 +72,6 @@ int16_t saturating_sub(int16_t a, int16_t b)
|
||||
}
|
||||
}
|
||||
|
||||
// Template adaptations for std::vector. This is needed because the avx functions expect 256 bit alignment.
|
||||
template <typename T, size_t alignment>
|
||||
class AlignedAllocator {
|
||||
public:
|
||||
static_assert(is_power_of_two(alignment), "Alignment should be power of 2");
|
||||
static_assert(alignment >= 8, "Alignment must be at least 8 bits");
|
||||
using value_type = T;
|
||||
|
||||
AlignedAllocator() = default;
|
||||
|
||||
AlignedAllocator(const AlignedAllocator &) = default;
|
||||
|
||||
AlignedAllocator &operator=(const AlignedAllocator &) = default;
|
||||
|
||||
template <typename U>
|
||||
struct rebind {
|
||||
using other = AlignedAllocator<U, alignment>;
|
||||
};
|
||||
|
||||
T *allocate(size_t n)
|
||||
{
|
||||
size_t alignment_bytes = alignment / 8;
|
||||
void *ptr = ::aligned_alloc(alignment_bytes, align_up(n * sizeof(T), alignment_bytes));
|
||||
return static_cast<T *>(ptr);
|
||||
}
|
||||
|
||||
void deallocate(T *p, size_t n)
|
||||
{
|
||||
::free(p);
|
||||
}
|
||||
};
|
||||
|
||||
// Using 512-aligned vector in case some functions use avx-512
|
||||
template <typename T>
|
||||
using AlignedAllocator512 = AlignedAllocator<T, 512>;
|
||||
template <typename T>
|
||||
using AlignedVector512 = std::vector<T, AlignedAllocator512<T>>;
|
||||
|
||||
void nr_ulsch_16qam_llr_ref(c16_t *rxdataF_comp, int32_t *ul_ch_mag, int16_t *ulsch_llr, uint32_t nb_re, uint8_t symbol)
|
||||
{
|
||||
int16_t *ul_ch_mag_i16 = (int16_t *)ul_ch_mag;
|
||||
@@ -190,27 +143,6 @@ void nr_ulsch_256qam_llr_ref(c16_t *rxdataF_comp,
|
||||
}
|
||||
}
|
||||
|
||||
AlignedVector512<c16_t> generate_random_c16(size_t num)
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937 rng(rd());
|
||||
std::uniform_int_distribution<int16_t> dist(INT16_MIN, INT16_MAX);
|
||||
AlignedVector512<c16_t> vec;
|
||||
vec.resize(num);
|
||||
auto gen = [&]() { return (c16_t){dist(rng), dist(rng)}; };
|
||||
std::generate(vec.begin(), vec.end(), gen);
|
||||
return vec;
|
||||
}
|
||||
|
||||
AlignedVector512<uint16_t> generate_random_uint16(size_t num)
|
||||
{
|
||||
AlignedVector512<uint16_t> vec;
|
||||
vec.resize(num);
|
||||
auto gen = [&]() { return static_cast<uint16_t>(std::rand()); };
|
||||
std::generate(vec.begin(), vec.end(), gen);
|
||||
return vec;
|
||||
}
|
||||
|
||||
void test_function_16_qam(AlignedVector512<uint32_t> nb_res)
|
||||
{
|
||||
for (auto i = 0U; i < nb_res.size(); i++) {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
//#include "PHY/defs_gNB.h"
|
||||
|
||||
/** @addtogroup _PHY_PARAMETER_ESTIMATION_BLOCKS_
|
||||
* @{
|
||||
*/
|
||||
|
||||
@@ -417,7 +417,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
//printf("start rx segment %d\n",r);
|
||||
uint32_t E = nr_get_E(G, harq_process->C, dlsch->dlsch_config.qamModOrder, dlsch->Nl, r);
|
||||
decParams.R = nr_get_R_ldpc_decoder(dlsch->dlsch_config.rv, E, decParams.BG, decParams.Z, &harq_process->llrLen, harq_process->DLround);
|
||||
union ldpcReqUnion id = {.s={dlsch->rnti,frame,nr_slot_rx,0,0}};
|
||||
union ldpcReqUnion id = {.s = {dlsch->rnti, frame, nr_slot_rx, 0, 0}};
|
||||
notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(ldpcDecode_ue_t), id.p, &nf, &nr_processDLSegment);
|
||||
ldpcDecode_ue_t * rdata=(ldpcDecode_ue_t *) NotifiedFifoData(req);
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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 __PHY_TEST_TOOLS_HPP__
|
||||
#define __PHY_TEST_TOOLS_HPP__
|
||||
|
||||
#include <vector>
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
extern "C" {
|
||||
#include "openair1/PHY/TOOLS/tools_defs.h"
|
||||
}
|
||||
|
||||
constexpr bool is_power_of_two(uint64_t n)
|
||||
{
|
||||
return n != 0 && (n & (n - 1)) == 0;
|
||||
}
|
||||
|
||||
size_t align_up(size_t a, size_t b)
|
||||
{
|
||||
return (a + b - 1) / b * b;
|
||||
}
|
||||
|
||||
// Template adaptations for std::vector. This is needed because the avx functions expect 256 bit alignment.
|
||||
template <typename T, size_t alignment>
|
||||
class AlignedAllocator {
|
||||
public:
|
||||
static_assert(is_power_of_two(alignment), "Alignment should be power of 2");
|
||||
static_assert(alignment >= 8, "Alignment must be at least 8 bits");
|
||||
using value_type = T;
|
||||
|
||||
AlignedAllocator() = default;
|
||||
|
||||
AlignedAllocator(const AlignedAllocator &) = default;
|
||||
|
||||
AlignedAllocator &operator=(const AlignedAllocator &) = default;
|
||||
|
||||
template <typename U>
|
||||
struct rebind {
|
||||
using other = AlignedAllocator<U, alignment>;
|
||||
};
|
||||
|
||||
T *allocate(size_t n)
|
||||
{
|
||||
size_t alignment_bytes = alignment / 8;
|
||||
void *ptr = ::aligned_alloc(alignment_bytes, align_up(n * sizeof(T), alignment_bytes));
|
||||
return static_cast<T *>(ptr);
|
||||
}
|
||||
|
||||
void deallocate(T *p, size_t n)
|
||||
{
|
||||
::free(p);
|
||||
}
|
||||
};
|
||||
|
||||
// Using 512-aligned vector in case some functions use avx-512
|
||||
template <typename T>
|
||||
using AlignedAllocator512 = AlignedAllocator<T, 512>;
|
||||
template <typename T>
|
||||
using AlignedVector512 = std::vector<T, AlignedAllocator512<T>>;
|
||||
|
||||
AlignedVector512<c16_t> generate_random_c16(size_t num)
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937 rng(rd());
|
||||
std::uniform_int_distribution<int16_t> dist(INT16_MIN, INT16_MAX);
|
||||
AlignedVector512<c16_t> vec;
|
||||
vec.resize(num);
|
||||
auto gen = [&]() { return (c16_t){dist(rng), dist(rng)}; };
|
||||
std::generate(vec.begin(), vec.end(), gen);
|
||||
return vec;
|
||||
}
|
||||
|
||||
AlignedVector512<uint16_t> generate_random_uint16(size_t num)
|
||||
{
|
||||
AlignedVector512<uint16_t> vec;
|
||||
vec.resize(num);
|
||||
auto gen = [&]() { return static_cast<uint16_t>(std::rand()); };
|
||||
std::generate(vec.begin(), vec.end(), gen);
|
||||
return vec;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3,3 +3,9 @@ target_link_libraries(test_signal_energy PRIVATE GTest::gtest UTIL)
|
||||
add_dependencies(tests test_signal_energy)
|
||||
add_test(NAME test_signal_energy
|
||||
COMMAND ./test_signal_energy)
|
||||
|
||||
add_executable(benchmark_rotate_vector benchmark_rotate_vector.cpp)
|
||||
target_link_libraries(benchmark_rotate_vector PRIVATE benchmark::benchmark UTIL PHY_NR)
|
||||
add_dependencies(tests benchmark_rotate_vector)
|
||||
add_test(NAME benchmark_rotate_vector
|
||||
COMMAND ./benchmark_rotate_vector)
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
extern "C" {
|
||||
#include "openair1/PHY/TOOLS/tools_defs.h"
|
||||
struct configmodule_interface_s;
|
||||
struct configmodule_interface_s *uniqCfg = NULL;
|
||||
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
|
||||
{
|
||||
if (assert) {
|
||||
abort();
|
||||
} else {
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
#include <cstdio>
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "openair1/PHY/TOOLS/phy_test_tools.hpp"
|
||||
|
||||
static void BM_rotate_cpx_vector(benchmark::State &state)
|
||||
{
|
||||
int vector_size = state.range(0);
|
||||
auto input_complex_16 = generate_random_c16(vector_size);
|
||||
auto input_alpha = generate_random_c16(vector_size);
|
||||
AlignedVector512<c16_t> output;
|
||||
output.resize(vector_size);
|
||||
int shift = 2;
|
||||
for (auto _ : state) {
|
||||
rotate_cpx_vector(input_complex_16.data(), input_alpha.data(), output.data(), vector_size, shift);
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK(BM_rotate_cpx_vector)->RangeMultiplier(4)->Range(100, 20000);
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
@@ -52,9 +52,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CEILIDIV(a,b) ((a+b-1)/b)
|
||||
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
||||
|
||||
typedef struct complexd {
|
||||
double r;
|
||||
double i;
|
||||
|
||||
+29
-171
@@ -53,23 +53,6 @@ typedef struct {
|
||||
int lut[MAX_PUCCH0_NID][160][14];
|
||||
} NR_gNB_PUCCH0_LUT_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t pbch_a;
|
||||
uint32_t pbch_a_interleaved;
|
||||
uint32_t pbch_a_prime;
|
||||
uint32_t pbch_e[NR_POLAR_PBCH_E_DWORD];
|
||||
} NR_gNB_PBCH;
|
||||
|
||||
|
||||
typedef enum {
|
||||
NR_SCH_IDLE,
|
||||
NR_ACTIVE,
|
||||
NR_CBA_ACTIVE,
|
||||
NR_DISABLED
|
||||
} NR_SCH_status_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// Nfapi DLSCH PDU
|
||||
nfapi_nr_dl_tti_pdsch_pdu pdsch_pdu;
|
||||
@@ -81,8 +64,6 @@ typedef struct {
|
||||
uint8_t **c;
|
||||
/// Frame where current HARQ round was sent
|
||||
uint32_t frame;
|
||||
/// Subframe where current HARQ round was sent
|
||||
uint32_t subframe;
|
||||
/// Interleaver outputs
|
||||
uint8_t *f;
|
||||
/// LDPC lifting size
|
||||
@@ -164,9 +145,6 @@ typedef struct {
|
||||
#define NUMBER_OF_NR_PRACH_MAX 8
|
||||
|
||||
typedef struct {
|
||||
/// \brief ?.
|
||||
/// first index: ? [0..1023] (hard coded)
|
||||
int16_t *prachF;
|
||||
/// \brief ?.
|
||||
/// second index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
|
||||
/// third index: frequency-domain sample [0..ofdm_symbol_size*12[
|
||||
@@ -221,6 +199,7 @@ typedef struct {
|
||||
int llrLen;
|
||||
//////////////////////////////////////////////////////////////
|
||||
} NR_UL_gNB_HARQ_t;
|
||||
|
||||
static inline int lenWithCrc(int nbSeg, int len)
|
||||
{
|
||||
if (nbSeg > 1)
|
||||
@@ -237,24 +216,8 @@ static inline int crcType(int nbSeg, int len)
|
||||
typedef struct {
|
||||
//! estimated rssi (dBm)
|
||||
int rx_rssi_dBm;
|
||||
//! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation)
|
||||
int rx_correlation[2];
|
||||
//! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation)
|
||||
int rx_correlation_dB[2];
|
||||
/// Wideband CQI (= SINR)
|
||||
int wideband_cqi[MAX_NUM_RU_PER_gNB];
|
||||
/// Wideband CQI in dB (= SINR dB)
|
||||
int wideband_cqi_dB[MAX_NUM_RU_PER_gNB];
|
||||
/// Wideband CQI (sum of all RX antennas, in dB)
|
||||
char wideband_cqi_tot;
|
||||
/// Subband CQI per RX antenna and RB (= SINR)
|
||||
int subband_cqi[MAX_NUM_RU_PER_gNB][275];
|
||||
/// Total Subband CQI and RB (= SINR)
|
||||
int subband_cqi_tot[275];
|
||||
/// Subband CQI in dB and RB (= SINR dB)
|
||||
int subband_cqi_dB[MAX_NUM_RU_PER_gNB][275];
|
||||
/// Total Subband CQI and RB
|
||||
int subband_cqi_tot_dB[275];
|
||||
} ulsch_measurements_gNB;
|
||||
|
||||
typedef struct {
|
||||
@@ -320,10 +283,6 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// \brief Holds the received data in the frequency domain for the allocated RBs in repeated format.
|
||||
/// - first index: rx antenna id [0..nb_antennas_rx[
|
||||
/// - second index: ? [0..2*ofdm_symbol_size[
|
||||
int32_t **rxdataF_ext;
|
||||
/// \brief Hold the channel estimates in time domain based on DRS.
|
||||
/// - first index: rx antenna id [0..nb_antennas_rx[
|
||||
/// - second index: ? [0..4*ofdm_symbol_size[
|
||||
@@ -332,10 +291,6 @@ typedef struct {
|
||||
/// - first index: rx antenna id [0..nb_antennas_rx[
|
||||
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
|
||||
int32_t **ul_ch_estimates;
|
||||
/// \brief Uplink channel estimates extracted in PRBS.
|
||||
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
|
||||
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
|
||||
int32_t **ul_ch_estimates_ext;
|
||||
/// \brief Holds the compensated signal.
|
||||
/// - first index: rx antenna id [0..nb_antennas_rx[
|
||||
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
|
||||
@@ -347,7 +302,7 @@ typedef struct {
|
||||
/// total signal over antennas
|
||||
uint32_t ulsch_power_tot;
|
||||
/// measured RX noise power
|
||||
int ulsch_noise_power[8];
|
||||
uint32_t ulsch_noise_power[8];
|
||||
/// total noise over antennas
|
||||
uint32_t ulsch_noise_power_tot;
|
||||
/// \brief llr values.
|
||||
@@ -379,7 +334,7 @@ typedef struct {
|
||||
/// Context data structure for RX/TX portion of slot processing
|
||||
typedef struct {
|
||||
/// Component Carrier index
|
||||
uint8_t CC_id;
|
||||
uint8_t CC_id;
|
||||
/// timestamp transmitted to HW
|
||||
openair0_timestamp timestamp_tx;
|
||||
/// slot to act upon for transmission
|
||||
@@ -393,111 +348,32 @@ typedef struct {
|
||||
/// \brief Instance count for RXn-TXnp4 processing thread.
|
||||
/// \internal This variable is protected by \ref mutex_rxtx.
|
||||
int instance_cnt;
|
||||
/// pthread structure for RXn-TXnp4 processing thread
|
||||
pthread_t pthread;
|
||||
/// pthread attributes for RXn-TXnp4 processing thread
|
||||
pthread_attr_t attr;
|
||||
/// condition variable for tx processing thread
|
||||
pthread_cond_t cond;
|
||||
/// mutex for RXn-TXnp4 processing thread
|
||||
pthread_mutex_t mutex;
|
||||
/// scheduling parameters for RXn-TXnp4 thread
|
||||
struct sched_param sched_param_rxtx;
|
||||
|
||||
/// \internal This variable is protected by \ref mutex_RUs_tx.
|
||||
int instance_cnt_RUs;
|
||||
/// condition variable for tx processing thread
|
||||
pthread_cond_t cond_RUs;
|
||||
/// mutex for L1 RXTX processing thread
|
||||
pthread_mutex_t mutex_RUs;
|
||||
/// mutex for L1 TX FH synchronization
|
||||
pthread_mutex_t mutex_RUs_tx;
|
||||
} gNB_L1_rxtx_proc_t;
|
||||
|
||||
|
||||
/// Context data structure for eNB slot processing
|
||||
typedef struct gNB_L1_proc_t_s {
|
||||
/// Component Carrier index
|
||||
uint8_t CC_id;
|
||||
/// thread index
|
||||
int thread_index;
|
||||
uint8_t CC_id;
|
||||
/// timestamp received from HW
|
||||
openair0_timestamp timestamp_rx;
|
||||
/// timestamp to send to "slave rru"
|
||||
openair0_timestamp timestamp_tx;
|
||||
/// slot to act upon for reception
|
||||
int slot_rx;
|
||||
/// slot to act upon for PRACH
|
||||
int slot_prach;
|
||||
/// frame to act upon for reception
|
||||
int frame_rx;
|
||||
/// frame to act upon for transmission
|
||||
int frame_tx;
|
||||
/// frame to act upon for PRACH
|
||||
int frame_prach;
|
||||
/// \internal This variable is protected by \ref mutex_td.
|
||||
int instance_cnt_td;
|
||||
/// \internal This variable is protected by \ref mutex_te.
|
||||
int instance_cnt_te;
|
||||
/// \internal This variable is protected by \ref mutex_prach.
|
||||
int instance_cnt_prach;
|
||||
/// \internal This variable is protected by \ref mutex_asynch_rxtx.
|
||||
int instance_cnt_asynch_rxtx;
|
||||
/// pthread structure for eNB single processing thread
|
||||
pthread_t pthread_single;
|
||||
/// pthread structure for asychronous RX/TX processing thread
|
||||
pthread_t pthread_asynch_rxtx;
|
||||
/// pthread structure for dumping L1 stats
|
||||
pthread_t L1_stats_thread;
|
||||
/// pthread structure for printing time meas
|
||||
pthread_t process_stats_thread;
|
||||
/// pthread structure for reordering L1 tx thread messages
|
||||
pthread_t pthread_tx_reorder;
|
||||
/// flag to indicate first RX acquisition
|
||||
int first_rx;
|
||||
/// flag to indicate first TX transmission
|
||||
int first_tx;
|
||||
/// pthread attributes for single gNB processing thread
|
||||
pthread_attr_t attr_single;
|
||||
/// pthread attributes for prach processing thread
|
||||
pthread_attr_t attr_prach;
|
||||
/// pthread attributes for asynchronous RX thread
|
||||
pthread_attr_t attr_asynch_rxtx;
|
||||
/// scheduling parameters for parallel turbo-decoder thread
|
||||
struct sched_param sched_param_td;
|
||||
/// scheduling parameters for parallel turbo-encoder thread
|
||||
struct sched_param sched_param_te;
|
||||
/// scheduling parameters for single eNB thread
|
||||
struct sched_param sched_param_single;
|
||||
/// scheduling parameters for prach thread
|
||||
struct sched_param sched_param_prach;
|
||||
/// scheduling parameters for asynch_rxtx thread
|
||||
struct sched_param sched_param_asynch_rxtx;
|
||||
pthread_cond_t cond_prach;
|
||||
/// condition variable for asynch RX/TX thread
|
||||
pthread_cond_t cond_asynch_rxtx;
|
||||
/// mutex for parallel turbo-decoder thread
|
||||
pthread_mutex_t mutex_td;
|
||||
/// mutex for parallel turbo-encoder thread
|
||||
pthread_mutex_t mutex_te;
|
||||
/// mutex for PRACH thread
|
||||
pthread_mutex_t mutex_prach;
|
||||
/// mutex for asynch RX/TX thread
|
||||
pthread_mutex_t mutex_asynch_rxtx;
|
||||
/// mutex for RU access to eNB processing (PDSCH/PUSCH)
|
||||
pthread_mutex_t mutex_RU;
|
||||
/// mutex for RU_tx access to eNB_tx processing (PDSCH/PUSCH)
|
||||
pthread_mutex_t mutex_RU_tx;
|
||||
/// mutex for RU access to eNB processing (PRACH)
|
||||
pthread_mutex_t mutex_RU_PRACH;
|
||||
/// mutex for RU access to eNB processing (PRACH BR)
|
||||
pthread_mutex_t mutex_RU_PRACH_br;
|
||||
/// mask for RUs serving eNB (PDSCH/PUSCH)
|
||||
int RU_mask, RU_mask_tx;
|
||||
/// mask for RUs serving eNB (PRACH)
|
||||
int RU_mask_prach;
|
||||
/// set of scheduling variables RXn-TXnp4 threads
|
||||
gNB_L1_rxtx_proc_t L1_proc, L1_proc_tx;
|
||||
gNB_L1_rxtx_proc_t L1_proc;
|
||||
gNB_L1_rxtx_proc_t L1_proc_tx;
|
||||
} gNB_L1_proc_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -523,8 +399,7 @@ typedef struct {
|
||||
//! estimated avg noise power per RB (dBm)
|
||||
int n0_subband_power_tot_dBm[275];
|
||||
/// PRACH background noise level
|
||||
int prach_I0;
|
||||
|
||||
int prach_I0;
|
||||
} PHY_MEASUREMENTS_gNB;
|
||||
|
||||
|
||||
@@ -539,25 +414,23 @@ typedef struct {
|
||||
/// Top-level PHY Data Structure for gNB
|
||||
typedef struct PHY_VARS_gNB_s {
|
||||
/// Module ID indicator for this instance
|
||||
module_id_t Mod_id;
|
||||
uint8_t CC_id;
|
||||
uint8_t configured;
|
||||
gNB_L1_proc_t proc;
|
||||
int abstraction_flag;
|
||||
int num_RU;
|
||||
RU_t *RU_list[MAX_NUM_RU_PER_gNB];
|
||||
module_id_t Mod_id;
|
||||
uint8_t CC_id;
|
||||
uint8_t configured;
|
||||
gNB_L1_proc_t proc;
|
||||
int num_RU;
|
||||
RU_t *RU_list[MAX_NUM_RU_PER_gNB];
|
||||
/// Ethernet parameters for northbound midhaul interface
|
||||
eth_params_t eth_params_n;
|
||||
eth_params_t eth_params_n;
|
||||
/// Ethernet parameters for fronthaul interface
|
||||
eth_params_t eth_params;
|
||||
int rx_total_gain_dB;
|
||||
int (*nr_start_if)(struct RU_t_s *ru, struct PHY_VARS_gNB_s *gNB);
|
||||
uint8_t local_flag;
|
||||
nfapi_nr_config_request_scf_t gNB_config;
|
||||
NR_DL_FRAME_PARMS frame_parms;
|
||||
eth_params_t eth_params;
|
||||
int rx_total_gain_dB;
|
||||
int (*nr_start_if)(struct RU_t_s *ru, struct PHY_VARS_gNB_s *gNB);
|
||||
nfapi_nr_config_request_scf_t gNB_config;
|
||||
NR_DL_FRAME_PARMS frame_parms;
|
||||
PHY_MEASUREMENTS_gNB measurements;
|
||||
NR_IF_Module_t *if_inst;
|
||||
NR_UL_IND_t UL_INFO;
|
||||
NR_IF_Module_t *if_inst;
|
||||
NR_UL_IND_t UL_INFO;
|
||||
|
||||
/// NFAPI RX ULSCH information
|
||||
nfapi_nr_rx_data_pdu_t rx_pdu_list[MAX_UL_PDUS_PER_SLOT];
|
||||
@@ -570,7 +443,7 @@ typedef struct PHY_VARS_gNB_s {
|
||||
/// NFAPI PRACH information
|
||||
nfapi_nr_prach_indication_pdu_t prach_pdu_indication_list[MAX_NUM_NR_RX_RACH_PDUS];
|
||||
|
||||
nfapi_nr_ul_tti_request_t UL_tti_req;
|
||||
nfapi_nr_ul_tti_request_t UL_tti_req;
|
||||
nfapi_nr_uci_indication_t uci_indication;
|
||||
|
||||
int max_nb_pucch;
|
||||
@@ -578,16 +451,15 @@ typedef struct PHY_VARS_gNB_s {
|
||||
int max_nb_pdsch;
|
||||
int max_nb_pusch;
|
||||
|
||||
NR_gNB_PBCH pbch;
|
||||
NR_gNB_COMMON common_vars;
|
||||
NR_gNB_PRACH prach_vars;
|
||||
NR_gNB_PRS prs_vars;
|
||||
NR_gNB_COMMON common_vars;
|
||||
NR_gNB_PRACH prach_vars;
|
||||
NR_gNB_PRS prs_vars;
|
||||
NR_gNB_PUSCH *pusch_vars;
|
||||
NR_gNB_PUCCH_t *pucch;
|
||||
NR_gNB_SRS_t *srs;
|
||||
NR_gNB_ULSCH_t *ulsch;
|
||||
NR_gNB_PHY_STATS_t phy_stats[MAX_MOBILES_PER_GNB];
|
||||
t_nrPolar_params **polarParams;
|
||||
t_nrPolar_params **polarParams;
|
||||
|
||||
/// SRS variables
|
||||
nr_srs_info_t **nr_srs_info;
|
||||
@@ -635,15 +507,11 @@ typedef struct PHY_VARS_gNB_s {
|
||||
uint64_t bad_pucch;
|
||||
int num_ulprbbl;
|
||||
int ulprbbl[275];
|
||||
/*
|
||||
time_stats_t phy_proc;
|
||||
*/
|
||||
|
||||
time_stats_t phy_proc_tx;
|
||||
time_stats_t phy_proc_rx;
|
||||
time_stats_t rx_prach;
|
||||
/*
|
||||
time_stats_t ofdm_mod_stats;
|
||||
*/
|
||||
|
||||
time_stats_t dlsch_encoding_stats;
|
||||
time_stats_t dlsch_modulation_stats;
|
||||
time_stats_t dlsch_scrambling_stats;
|
||||
@@ -678,10 +546,6 @@ typedef struct PHY_VARS_gNB_s {
|
||||
time_stats_t srs_beam_report_stats;
|
||||
time_stats_t srs_iq_matrix_stats;
|
||||
|
||||
/*
|
||||
time_stats_t rx_dft_stats;
|
||||
time_stats_t ulsch_freq_offset_estimation_stats;
|
||||
*/
|
||||
notifiedFIFO_t respPuschSymb;
|
||||
notifiedFIFO_t respDecode;
|
||||
notifiedFIFO_t resp_L1;
|
||||
@@ -739,7 +603,7 @@ typedef struct LDPCDecode_s {
|
||||
struct ldpcReqId {
|
||||
uint16_t rnti;
|
||||
uint16_t frame;
|
||||
uint8_t subframe;
|
||||
uint8_t slot;
|
||||
uint8_t codeblock;
|
||||
uint16_t spare;
|
||||
} __attribute__((packed));
|
||||
@@ -756,12 +620,6 @@ typedef struct processingData_L1 {
|
||||
PHY_VARS_gNB *gNB;
|
||||
} processingData_L1_t;
|
||||
|
||||
typedef enum {
|
||||
FILLED,
|
||||
FILLING,
|
||||
NOT_FILLED
|
||||
} msgStatus_t;
|
||||
|
||||
typedef struct processingData_L1tx {
|
||||
int frame;
|
||||
int slot;
|
||||
|
||||
@@ -384,7 +384,7 @@ typedef struct PHY_VARS_NR_UE_s {
|
||||
NR_UE_COMMON common_vars;
|
||||
|
||||
nr_ue_if_module_t *if_inst;
|
||||
|
||||
bool received_config_request;
|
||||
fapi_nr_config_request_t nrUE_config;
|
||||
nr_synch_request_t synch_request;
|
||||
|
||||
@@ -450,11 +450,9 @@ typedef struct PHY_VARS_NR_UE_s {
|
||||
int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
uint8_t decode_SIB;
|
||||
uint8_t decode_MIB;
|
||||
uint8_t init_sync_frame;
|
||||
uint8_t init_sync_frame;
|
||||
/// temporary offset during cell search prior to MIB decoding
|
||||
int ssb_offset;
|
||||
int ssb_offset;
|
||||
uint16_t symbol_offset; /// offset in terms of symbols for detected ssb in sync
|
||||
int64_t max_pos_iir; /// Timing offset IIR filter
|
||||
int max_pos_acc; /// Timing offset accumuluated error for PI filter
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
extern uint8_t nfapi_mode;
|
||||
|
||||
void nr_common_signal_procedures(PHY_VARS_gNB *gNB,int frame,int slot, nfapi_nr_dl_tti_ssb_pdu ssb_pdu)
|
||||
void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr_dl_tti_ssb_pdu ssb_pdu)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
@@ -135,10 +135,9 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB,int frame,int slot, nfapi_nr_
|
||||
gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value;
|
||||
}
|
||||
|
||||
nr_generate_pbch(&ssb_pdu,
|
||||
gNB->nr_pbch_interleaver,
|
||||
nr_generate_pbch(gNB,
|
||||
&ssb_pdu,
|
||||
&txdataF[0][txdataF_offset],
|
||||
gNB->TX_AMP,
|
||||
ssb_start_symbol,
|
||||
n_hf,
|
||||
frame,
|
||||
@@ -346,10 +345,7 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
|
||||
ulsch_harq->ulsch_pdu.rb_size],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB *
|
||||
ulsch_harq->ulsch_pdu.rb_size)),1,1); LOG_M("chestF0.m","chF0",
|
||||
&gNB->pusch_vars[0].ul_ch_estimates[0][ulsch_harq->ulsch_pdu.start_symbol_index*gNB->frame_parms.ofdm_symbol_size],gNB->frame_parms.ofdm_symbol_size,1,1);
|
||||
LOG_M("chestF0_ext.m","chF0_ext",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates_ext[0][(ulsch_harq->ulsch_pdu.start_symbol_index+1)*(off+(NR_NB_SC_PER_RB *
|
||||
ulsch_harq->ulsch_pdu.rb_size))], (ulsch_harq->ulsch_pdu.nr_of_symbols-1)*(off+(NR_NB_SC_PER_RB *
|
||||
ulsch_harq->ulsch_pdu.rb_size)),1,1); LOG_M("rxsigF0_comp.m","rxsF0_comp",
|
||||
LOG_M("rxsigF0_comp.m","rxsF0_comp",
|
||||
&gNB->pusch_vars[0].rxdataF_comp[0][ulsch_harq->ulsch_pdu.start_symbol_index*(off+(NR_NB_SC_PER_RB *
|
||||
ulsch_harq->ulsch_pdu.rb_size))],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB *
|
||||
ulsch_harq->ulsch_pdu.rb_size)),1,1); LOG_M("rxsigF0_llr.m","rxsF0_llr",
|
||||
@@ -361,10 +357,7 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
|
||||
ulsch_harq->ulsch_pdu.rb_size],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB *
|
||||
ulsch_harq->ulsch_pdu.rb_size)),1,1); LOG_M("chestF1.m","chF1",
|
||||
&gNB->pusch_vars[0].ul_ch_estimates[1][ulsch_harq->ulsch_pdu.start_symbol_index*gNB->frame_parms.ofdm_symbol_size],gNB->frame_parms.ofdm_symbol_size,1,1);
|
||||
LOG_M("chestF1_ext.m","chF1_ext",
|
||||
&gNB->pusch_vars[0].ul_ch_estimates_ext[1][(ulsch_harq->ulsch_pdu.start_symbol_index+1)*(off+(NR_NB_SC_PER_RB *
|
||||
ulsch_harq->ulsch_pdu.rb_size))], (ulsch_harq->ulsch_pdu.nr_of_symbols-1)*(off+(NR_NB_SC_PER_RB *
|
||||
ulsch_harq->ulsch_pdu.rb_size)),1,1); LOG_M("rxsigF1_comp.m","rxsF1_comp",
|
||||
LOG_M("rxsigF1_comp.m","rxsF1_comp",
|
||||
&gNB->pusch_vars[0].rxdataF_comp[1][ulsch_harq->ulsch_pdu.start_symbol_index*(off+(NR_NB_SC_PER_RB *
|
||||
ulsch_harq->ulsch_pdu.rb_size))],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB *
|
||||
ulsch_harq->ulsch_pdu.rb_size)),1,1);
|
||||
|
||||
@@ -549,13 +549,14 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config)
|
||||
void nr_ue_phy_config_request(nr_phy_config_t *phy_config)
|
||||
{
|
||||
fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config;
|
||||
PHY_VARS_NR_UE *phy = PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id];
|
||||
fapi_nr_config_request_t *nrUE_config = &phy->nrUE_config;
|
||||
if(phy_config != NULL) {
|
||||
phy->received_config_request = true;
|
||||
memcpy(nrUE_config, &phy_config->config_req, sizeof(fapi_nr_config_request_t));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nr_ue_synch_request(nr_synch_request_t *synch_request)
|
||||
@@ -567,8 +568,10 @@ void nr_ue_synch_request(nr_synch_request_t *synch_request)
|
||||
|
||||
void nr_ue_sl_phy_config_request(nr_sl_phy_config_t *phy_config)
|
||||
{
|
||||
sl_nr_phy_config_request_t *sl_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->SL_UE_PHY_PARAMS.sl_config;
|
||||
PHY_VARS_NR_UE *phy = PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id];
|
||||
sl_nr_phy_config_request_t *sl_config = &phy->SL_UE_PHY_PARAMS.sl_config;
|
||||
if (phy_config != NULL) {
|
||||
phy->received_config_request = true;
|
||||
memcpy(sl_config, &phy_config->sl_config_req, sizeof(sl_nr_phy_config_request_t));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
|
||||
|
||||
/**\brief NR UE FAPI-like P5 message, physical configuration from L2 to configure L1
|
||||
\param scheduled_response including transmission config(dl_config, ul_config) and data transmission (tx_req)*/
|
||||
int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config);
|
||||
void nr_ue_phy_config_request(nr_phy_config_t *phy_config);
|
||||
void nr_ue_sl_phy_config_request(nr_sl_phy_config_t *phy_config);
|
||||
|
||||
/**\brief NR UE FAPI message to schedule a synchronization with target gNB
|
||||
|
||||
@@ -204,6 +204,7 @@ int main(int argc, char **argv)
|
||||
|
||||
channel_desc_t *gNB2UE;
|
||||
get_softmodem_params()->sa = 1;
|
||||
get_softmodem_params()->usim_test = 1;
|
||||
|
||||
//uint8_t extended_prefix_flag=0;
|
||||
//int8_t interf1=-21,interf2=-21;
|
||||
@@ -230,7 +231,7 @@ int main(int argc, char **argv)
|
||||
int frame_length_complex_samples_no_prefix;
|
||||
NR_DL_FRAME_PARMS *frame_parms;
|
||||
|
||||
int ret, payload_ret=0;
|
||||
int ret;
|
||||
int run_initial_sync=0;
|
||||
|
||||
int loglvl=OAILOG_WARNING;
|
||||
@@ -835,17 +836,15 @@ int main(int argc, char **argv)
|
||||
rxdataF);
|
||||
|
||||
if (ret == 0) {
|
||||
// UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically
|
||||
// UE->rx_ind.rx_indication_body->mib_pdu.ssb_length; //Lmax, not yet detected automatically
|
||||
uint8_t gNB_xtra_byte = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
gNB_xtra_byte |= ((gNB->pbch.pbch_a >> (31 - i)) & 1) << (7 - i);
|
||||
|
||||
payload_ret = (result.xtra_byte == gNB_xtra_byte);
|
||||
for (i = 0; i < 3; i++) {
|
||||
payload_ret +=
|
||||
(result.decoded_output[i] == ((msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload >> (8 * i)) & 0xff));
|
||||
}
|
||||
uint32_t xtra_byte = nr_pbch_extra_byte_generation(frame,
|
||||
n_hf,
|
||||
ssb_index,
|
||||
gNB->gNB_config.ssb_table.ssb_subcarrier_offset.value,
|
||||
frame_parms->Lmax);
|
||||
int payload_ret = (result.xtra_byte == xtra_byte);
|
||||
nfapi_nr_dl_tti_ssb_pdu_rel15_t *pdu = &msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15;
|
||||
for (int i = 0; i < 3; i++)
|
||||
payload_ret += (result.decoded_output[i] == ((pdu->bchPayload >> (8 * i)) & 0xff));
|
||||
// printf("ret %d\n", payload_ret);
|
||||
if (payload_ret != 4)
|
||||
n_errors_payload++;
|
||||
|
||||
@@ -135,11 +135,6 @@ int main(int argc, char **argv){
|
||||
int prachOccasion = 0;
|
||||
double DS_TDL = .03;
|
||||
|
||||
// int8_t interf1=-19,interf2=-19;
|
||||
// uint8_t abstraction_flag=0,calibration_flag=0;
|
||||
// double prach_sinr;
|
||||
// uint32_t nsymb;
|
||||
// uint16_t preamble_max, preamble_energy_max;
|
||||
FILE *input_fd=NULL;
|
||||
char* input_file=NULL;
|
||||
int n_bytes=0;
|
||||
@@ -784,22 +779,21 @@ int main(int argc, char **argv){
|
||||
|
||||
if (n_frames==1) {
|
||||
printf("preamble %d (tx %d) : energy %d, delay %d\n",preamble_rx,preamble_tx,preamble_energy,preamble_delay);
|
||||
#ifdef NR_PRACH_DEBUG
|
||||
LOG_M("prach0.m","prach0", &txdata[0][prach_start], frame_parms->samples_per_subframe, 1, 1);
|
||||
LOG_M("prachF0.m","prachF0", &gNB->prach_vars.prachF[0], N_ZC, 1, 1);
|
||||
LOG_M("rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
|
||||
LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
|
||||
LOG_M("ru_rxsigF0.m","rxsF0", ru->common.rxdataF[0], frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot, 1, 1);
|
||||
LOG_M("ru_prach_rxsigF0.m","rxsF0", ru->prach_rxsigF[0][0], N_ZC, 1, 1);
|
||||
LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1);
|
||||
LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1);
|
||||
#endif
|
||||
#ifdef NR_PRACH_DEBUG
|
||||
LOG_M("prach0.m","prach0", &txdata[0][prach_start], frame_parms->samples_per_subframe, 1, 1);
|
||||
LOG_M("rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
|
||||
LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
|
||||
LOG_M("ru_rxsigF0.m","rxsF0", ru->common.rxdataF[0], frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot, 1, 1);
|
||||
LOG_M("ru_prach_rxsigF0.m","rxsF0", ru->prach_rxsigF[0][0], N_ZC, 1, 1);
|
||||
LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1);
|
||||
LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
printf("SNR %f dB, UE Speed %f km/h: errors %u/%d (delay %f)\n", SNR, ue_speed, prach_errors, n_frames, delay_avg/(double)(n_frames-prach_errors));
|
||||
if (input_fd)
|
||||
break;
|
||||
break;
|
||||
if (prach_errors)
|
||||
break;
|
||||
|
||||
|
||||
@@ -1266,30 +1266,20 @@ int main(int argc, char *argv[])
|
||||
if (n_trials == 1 && round == 0) {
|
||||
__attribute__((unused)) int off = ((nb_rb & 1) == 1) ? 4 : 0;
|
||||
|
||||
LOG_M("rxsigF0_ext.m",
|
||||
"rxsF0_ext",
|
||||
&pusch_vars->rxdataF_ext[0][start_symbol * NR_NB_SC_PER_RB * pusch_pdu->rb_size],
|
||||
nb_symb_sch * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
LOG_M("chestF0.m",
|
||||
"chF0",
|
||||
&pusch_vars->ul_ch_estimates[0][start_symbol * frame_parms->ofdm_symbol_size],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
1,
|
||||
1);
|
||||
LOG_M("chestF0_ext.m",
|
||||
"chF0_ext",
|
||||
&pusch_vars->ul_ch_estimates_ext[0][(start_symbol + 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
|
||||
(nb_symb_sch - 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
|
||||
LOG_M("rxsigF0_comp.m",
|
||||
"rxsF0_comp",
|
||||
&pusch_vars->rxdataF_comp[0][start_symbol * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
|
||||
nb_symb_sch * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
|
||||
LOG_M("rxsigF0_llrlayers0.m",
|
||||
"rxsF0_llrlayers0",
|
||||
&pusch_vars->llr_layers[0][0],
|
||||
@@ -1298,12 +1288,6 @@ int main(int argc, char *argv[])
|
||||
0);
|
||||
|
||||
if (precod_nbr_layers == 2) {
|
||||
LOG_M("rxsigF1_ext.m",
|
||||
"rxsF1_ext",
|
||||
&pusch_vars->rxdataF_ext[1][start_symbol * NR_NB_SC_PER_RB * pusch_pdu->rb_size],
|
||||
nb_symb_sch * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
|
||||
LOG_M("chestF3.m",
|
||||
"chF3",
|
||||
@@ -1312,13 +1296,6 @@ int main(int argc, char *argv[])
|
||||
1,
|
||||
1);
|
||||
|
||||
LOG_M("chestF3_ext.m",
|
||||
"chF3_ext",
|
||||
&pusch_vars->ul_ch_estimates_ext[3][(start_symbol + 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
|
||||
(nb_symb_sch - 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
|
||||
LOG_M("rxsigF2_comp.m",
|
||||
"rxsF2_comp",
|
||||
&pusch_vars->rxdataF_comp[2][start_symbol * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
|
||||
@@ -1335,24 +1312,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (precod_nbr_layers == 4) {
|
||||
LOG_M("rxsigF1_ext.m",
|
||||
"rxsF1_ext",
|
||||
&pusch_vars->rxdataF_ext[1][start_symbol * NR_NB_SC_PER_RB * pusch_pdu->rb_size],
|
||||
nb_symb_sch * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
LOG_M("rxsigF2_ext.m",
|
||||
"rxsF2_ext",
|
||||
&pusch_vars->rxdataF_ext[2][start_symbol * NR_NB_SC_PER_RB * pusch_pdu->rb_size],
|
||||
nb_symb_sch * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
LOG_M("rxsigF3_ext.m",
|
||||
"rxsF3_ext",
|
||||
&pusch_vars->rxdataF_ext[3][start_symbol * NR_NB_SC_PER_RB * pusch_pdu->rb_size],
|
||||
nb_symb_sch * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
|
||||
LOG_M("chestF5.m",
|
||||
"chF5",
|
||||
@@ -1373,25 +1332,6 @@ int main(int argc, char *argv[])
|
||||
1,
|
||||
1);
|
||||
|
||||
LOG_M("chestF5_ext.m",
|
||||
"chF5_ext",
|
||||
&pusch_vars->ul_ch_estimates_ext[5][(start_symbol + 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
|
||||
(nb_symb_sch - 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
LOG_M("chestF10_ext.m",
|
||||
"chF10_ext",
|
||||
&pusch_vars->ul_ch_estimates_ext[10][(start_symbol + 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
|
||||
(nb_symb_sch - 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
LOG_M("chestF15_ext.m",
|
||||
"chF15_ext",
|
||||
&pusch_vars->ul_ch_estimates_ext[15][(start_symbol + 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
|
||||
(nb_symb_sch - 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size)),
|
||||
1,
|
||||
1);
|
||||
|
||||
LOG_M("rxsigF4_comp.m",
|
||||
"rxsF4_comp",
|
||||
&pusch_vars->rxdataF_comp[4][start_symbol * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
|
||||
|
||||
@@ -1620,7 +1620,6 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id,
|
||||
|
||||
if (!get_softmodem_params()->emulate_l1)
|
||||
mac->if_module->phy_config_request(&mac->phy_config);
|
||||
mac->phy_config_request_sent = true;
|
||||
}
|
||||
|
||||
void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id,
|
||||
@@ -1676,7 +1675,6 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac,
|
||||
mac->synch_request.synch_req.target_Nid_cell = mac->physCellId;
|
||||
mac->if_module->synch_request(&mac->synch_request);
|
||||
mac->if_module->phy_config_request(&mac->phy_config);
|
||||
mac->phy_config_request_sent = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -541,8 +541,6 @@ typedef struct NR_UE_MAC_INST_s {
|
||||
|
||||
NR_UL_TIME_ALIGNMENT_t ul_time_alignment;
|
||||
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon;
|
||||
|
||||
bool phy_config_request_sent;
|
||||
frame_type_t frame_type;
|
||||
|
||||
/* Random Access */
|
||||
|
||||
@@ -59,7 +59,6 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
|
||||
nr_ue_reset_sync_state(mac);
|
||||
mac->get_sib1 = false;
|
||||
mac->get_otherSI = false;
|
||||
mac->phy_config_request_sent = false;
|
||||
memset(&mac->phy_config, 0, sizeof(mac->phy_config));
|
||||
mac->si_window_start = -1;
|
||||
mac->servCellIndex = 0;
|
||||
|
||||
@@ -346,7 +346,7 @@ static bool is_my_dci(NR_UE_MAC_INST_t *mac, nfapi_nr_dl_dci_pdu_t *received_pdu
|
||||
if (get_softmodem_params()->sa) {
|
||||
if (mac->state == UE_NOT_SYNC)
|
||||
return false;
|
||||
if (received_pdu->RNTI == 0xFFFF && mac->phy_config_request_sent)
|
||||
if (received_pdu->RNTI == 0xFFFF)
|
||||
return false;
|
||||
if (received_pdu->RNTI != mac->crnti && mac->ra.ra_state == nrRA_SUCCEEDED)
|
||||
return false;
|
||||
@@ -1149,7 +1149,7 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info)
|
||||
|
||||
LOG_T(NR_MAC, "Not calling scheduler mac->ra.ra_state = %d\n", mac->ra.ra_state);
|
||||
|
||||
if (mac->phy_config_request_sent && is_nr_UL_slot(mac->tdd_UL_DL_ConfigurationCommon, ul_info->slot, mac->frame_type))
|
||||
if (is_nr_UL_slot(mac->tdd_UL_DL_ConfigurationCommon, ul_info->slot, mac->frame_type))
|
||||
nr_ue_ul_scheduler(mac, ul_info);
|
||||
pthread_mutex_unlock(&mac_IF_mutex);
|
||||
|
||||
|
||||
@@ -227,18 +227,12 @@ typedef void (nr_sl_ue_scheduled_response_f)(nr_scheduled_response_t *sl_schedul
|
||||
/*
|
||||
* Generic type of an application-defined callback to return various
|
||||
* types of data to the application.
|
||||
* EXPECTED RETURN VALUES:
|
||||
* -1: Failed to consume bytes. Abort the mission.
|
||||
* Non-negative return values indicate success, and ignored.
|
||||
*/
|
||||
typedef int8_t (nr_ue_phy_config_request_f)(nr_phy_config_t *phy_config);
|
||||
typedef void (nr_ue_phy_config_request_f)(nr_phy_config_t *phy_config);
|
||||
|
||||
/*
|
||||
* Generic type of an application-defined callback to return various
|
||||
* types of data to the application.
|
||||
* EXPECTED RETURN VALUES:
|
||||
* -1: Failed to consume bytes. Abort the mission.
|
||||
* Non-negative return values indicate success, and ignored.
|
||||
*/
|
||||
typedef void(nr_ue_sl_phy_config_request_f)(nr_sl_phy_config_t *sl_phy_config);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
# include "nas_parser.h"
|
||||
# include "nas_proc.h"
|
||||
#include "common/utils/mem/oai_memory.h"
|
||||
#include "common/oai_version.h"
|
||||
|
||||
#include "nas_user.h"
|
||||
#include "common/ran_context.h"
|
||||
@@ -134,7 +135,7 @@ void *nas_ue_task(void *args_p)
|
||||
user->at_response = calloc_or_fail(1, sizeof(at_response_t));
|
||||
user->lowerlayer_data = calloc_or_fail(1, sizeof(lowerlayer_data_t));
|
||||
/* Initialize NAS user */
|
||||
nas_user_initialize(user, &user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION);
|
||||
nas_user_initialize(user, &user_api_emm_callback, &user_api_esm_callback, OAI_FIRMWARE_VERSION);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -174,7 +175,7 @@ void *nas_ue_task(void *args_p)
|
||||
user->at_response = calloc_or_fail(1, sizeof(at_response_t));
|
||||
user->lowerlayer_data = calloc_or_fail(1, sizeof(lowerlayer_data_t));
|
||||
/* Initialize NAS user */
|
||||
nas_user_initialize(user, &user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION);
|
||||
nas_user_initialize(user, &user_api_emm_callback, &user_api_esm_callback, OAI_FIRMWARE_VERSION);
|
||||
user->ueid = 0;
|
||||
}
|
||||
|
||||
|
||||
+10
-1
@@ -92,10 +92,19 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
|
||||
|
||||
rx_sym = callback_tag->symbol;
|
||||
uint32_t ru_id = callback_tag->oXuId;
|
||||
|
||||
LOG_D(NR_PHY,
|
||||
"rx_callback frame %d, subframe %d, slot %d, second %lld, rx_sym %d ru_id %d\n",
|
||||
frame,
|
||||
subframe,
|
||||
slot,
|
||||
(unsigned long long)second,
|
||||
rx_sym,
|
||||
ru_id);
|
||||
if (rx_sym == 7) {
|
||||
if (first_call_set) {
|
||||
if (!first_rx_set) {
|
||||
LOG_I(NR_PHY, "first_rx is set (num_ports %d)\n", num_ports);
|
||||
LOG_I(NR_PHY, "first_rx is set (num_ports %d), first_read_set %d\n", num_ports, first_read_set);
|
||||
}
|
||||
first_rx_set = 1;
|
||||
if (first_read_set == 1) {
|
||||
|
||||
@@ -392,8 +392,8 @@ static void oran_allocate_buffers(void *handle,
|
||||
}
|
||||
}
|
||||
|
||||
xran_5g_fronthault_config(pi->instanceHandle, src, srccp, dst, dstcp, oai_xran_fh_rx_callback, &portInstances->RxCbTag[0][0]);
|
||||
xran_5g_prach_req(pi->instanceHandle, prach, prachdecomp, oai_xran_fh_rx_prach_callback, &portInstances->PrachCbTag[0][0]);
|
||||
xran_5g_fronthault_config(pi->instanceHandle, src, srccp, dst, dstcp, oai_xran_fh_rx_callback, &portInstances->pusch_tag);
|
||||
xran_5g_prach_req(pi->instanceHandle, prach, prachdecomp, oai_xran_fh_rx_prach_callback, &portInstances->prach_tag);
|
||||
}
|
||||
|
||||
int *oai_oran_initialize(const openair0_config_t *openair0_cfg)
|
||||
@@ -432,7 +432,11 @@ int *oai_oran_initialize(const openair0_config_t *openair0_cfg)
|
||||
}
|
||||
|
||||
int sector = 0;
|
||||
printf("Initialize ORAN port instance %d (%d) sector %d\n", o_xu_id, init.xran_ports, sector);
|
||||
oran_port_instance_t *pi = &gPortInst[o_xu_id][sector];
|
||||
struct xran_cb_tag tag = {.cellId = sector, .oXuId = o_xu_id};
|
||||
pi->prach_tag = tag;
|
||||
pi->pusch_tag = tag;
|
||||
oran_allocate_buffers(gxran_handle, o_xu_id, 1, pi, &xran_fh_config[o_xu_id]);
|
||||
|
||||
if ((xret = xran_reg_physide_cb(gxran_handle, oai_physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI)) != XRAN_STATUS_SUCCESS) {
|
||||
|
||||
@@ -50,8 +50,8 @@ typedef struct oran_port_instance_t {
|
||||
void *instanceHandle;
|
||||
//uint32_t dpdkPoolIndex[MAX_SW_XRAN_INTERFACE_NUM];
|
||||
|
||||
struct xran_cb_tag RxCbTag[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR];
|
||||
struct xran_cb_tag PrachCbTag[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR];
|
||||
struct xran_cb_tag prach_tag;
|
||||
struct xran_cb_tag pusch_tag;
|
||||
} oran_port_instance_t;
|
||||
|
||||
extern struct xran_fh_config gxran_fh_config[XRAN_PORTS_NUM];
|
||||
|
||||
@@ -182,6 +182,8 @@ typedef struct {
|
||||
|
||||
static int allocCirBuf(rfsimulator_state_t *bridge, int sock)
|
||||
{
|
||||
/* TODO: cleanup code so that this AssertFatal becomes useless */
|
||||
AssertFatal(sock >= 0 && sock < sizeofArray(bridge->buf), "socket %d is not in range\n", sock);
|
||||
buffer_t *ptr=&bridge->buf[sock];
|
||||
ptr->circularBuf = calloc(1, sampleToByte(CirSize, 1));
|
||||
if (ptr->circularBuf == NULL) {
|
||||
@@ -302,7 +304,12 @@ static void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t)
|
||||
while (count) {
|
||||
l = write(fd, buf, count);
|
||||
|
||||
if (l <= 0) {
|
||||
if (l == 0) {
|
||||
LOG_E(HW, "write() failed, returned 0\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (l < 0) {
|
||||
if (errno==EINTR)
|
||||
continue;
|
||||
|
||||
@@ -310,8 +317,10 @@ static void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t)
|
||||
LOG_D(HW, "write() failed, errno(%d)\n", errno);
|
||||
usleep(250);
|
||||
continue;
|
||||
} else
|
||||
} else {
|
||||
LOG_E(HW, "write() failed, errno(%d)\n", errno);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
count -= l;
|
||||
|
||||
+289
@@ -0,0 +1,289 @@
|
||||
Active_gNBs = ( "gNB-OAI-DU");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
gNB_DU_ID = 0xe00;
|
||||
gNB_name = "gNB-OAI-DU";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ( { sst = 1; }); });
|
||||
|
||||
nr_cellid = 1;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pdsch_AntennaPorts_N1 = 2;
|
||||
pusch_AntennaPorts = 8;
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 0 ;
|
||||
sib1_tda = 15;
|
||||
# force_UL256qam_off = 1;
|
||||
maxMIMO_layers = 2;
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
controlResourceSetZero = 11;
|
||||
searchSpaceZero = 0;
|
||||
}
|
||||
);
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
# n_TimingAdvanceOffset = 0;
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3430.56 MHz (center frequency)
|
||||
absoluteFrequencySSB = 628704;
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3411.48 MHz
|
||||
dl_absoluteFrequencyPointA = 627432;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 106;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
initialDLBWPlocationAndBandwidth = 28875; #38.101-1 Table 5.3.2-1
|
||||
#
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 11;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 106;
|
||||
pMax = 23;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 28875;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 154;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 0;
|
||||
preambleReceivedTargetPower = -100;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 8;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 3;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 5;
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
|
||||
# this is the offset between the last PRACH preamble power and the Msg3 PUSCH, 2 times the field value in dB
|
||||
msg3_DeltaPreamble = 2;
|
||||
p0_NominalWithGrant = -96;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 0;
|
||||
p0_nominal = -96;
|
||||
# ssb_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
ssb_PositionsInBurst_Bitmap = 0x10001L;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 1;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 8=ms3 9=ms4
|
||||
referenceSubcarrierSpacing = 1;
|
||||
dl_UL_TransmissionPeriodicity = 8;
|
||||
nrofDownlinkSlots = 3;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "f1";
|
||||
local_n_if_name = "enp193s0f0";
|
||||
local_n_address = "172.21.16.51";
|
||||
remote_n_address = "172.21.6.90";
|
||||
local_n_portc = 500;
|
||||
local_n_portd = 2153;
|
||||
remote_n_portc = 501;
|
||||
remote_n_portd = 2153;
|
||||
pusch_TargetSNRx10 = 230;
|
||||
pucch_TargetSNRx10 = 270;
|
||||
dl_bler_target_upper = .35;
|
||||
dl_bler_target_lower = .15;
|
||||
ul_bler_target_upper = .35;
|
||||
ul_bler_target_lower = .15;
|
||||
pusch_FailureThres = 100;
|
||||
ul_max_mcs = 28;
|
||||
}
|
||||
);
|
||||
|
||||
L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 100;
|
||||
pucch0_dtx_threshold = 80;
|
||||
pusch_dtx_threshold = 10;
|
||||
max_ldpc_iterations = 10;
|
||||
tx_amp_backoff_dB = 12; # needs to match O-RU configuration
|
||||
L1_rx_thread_core = 8;
|
||||
L1_tx_thread_core = 10; # relevant after merge of l1_tx_thread
|
||||
phase_compensation = 0; # needs to match O-RU configuration
|
||||
}
|
||||
);
|
||||
|
||||
RUs = (
|
||||
{
|
||||
local_rf = "no";
|
||||
nb_tx = 8;
|
||||
nb_rx = 8;
|
||||
att_tx = 0
|
||||
att_rx = 0;
|
||||
bands = [78];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
sf_extension = 0;
|
||||
eNB_instances = [0];
|
||||
ru_thread_core = 9;
|
||||
sl_ahead = 10;
|
||||
clock_src = "internal";
|
||||
tr_preference = "raw_if4p5"; # important: activate FHI7.2
|
||||
do_precoding = 0; # needs to match O-RU configuration
|
||||
}
|
||||
);
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level = "info";
|
||||
hw_log_level = "info";
|
||||
phy_log_level = "info";
|
||||
mac_log_level = "info";
|
||||
rlc_log_level = "info";
|
||||
f1ap_log_level = "info";
|
||||
};
|
||||
|
||||
fhi_72 = {
|
||||
dpdk_devices = ("0000:01:01.0", "0000:01:01.1", "0000:01:01.2", "0000:01:01.3");
|
||||
system_core = 0;
|
||||
io_core = 1;
|
||||
worker_cores = (2);
|
||||
du_addr = ("00:11:22:33:44:66","00:11:22:33:44:67","00:11:22:33:44:68","00:11:22:33:44:69");
|
||||
ru_addr = ("70:b3:d5:e1:5b:ff","70:b3:d5:e1:5b:ff","70:b3:d5:e1:5b:81", "70:b3:d5:e1:5b:81");
|
||||
mtu = 9216;
|
||||
file_prefix = "fhi_72";
|
||||
fh_config = (
|
||||
# RAN650
|
||||
{
|
||||
Tadv_cp_dl = 125;
|
||||
T2a_cp_dl = (259, 500);
|
||||
T2a_cp_ul = (25, 500);
|
||||
T2a_up = (134, 375);
|
||||
Ta3 = (152, 160);
|
||||
T1a_cp_dl = (419, 470);
|
||||
T1a_cp_ul = (285, 336);
|
||||
T1a_up = (294, 345);
|
||||
Ta4 = (0, 200);
|
||||
ru_config = {
|
||||
iq_width = 9;
|
||||
iq_width_prach = 9;
|
||||
};
|
||||
prach_config = {
|
||||
eAxC_offset = 4;
|
||||
};
|
||||
},
|
||||
# RAN550
|
||||
{
|
||||
Tadv_cp_dl = 125;
|
||||
T2a_cp_dl = (259, 500);
|
||||
T2a_cp_ul = (25, 500);
|
||||
T2a_up = (134, 375);
|
||||
Ta3 = (152, 160);
|
||||
T1a_cp_dl = (419, 470);
|
||||
T1a_cp_ul = (285, 336);
|
||||
T1a_up = (294, 345);
|
||||
Ta4 = (0, 200);
|
||||
ru_config = {
|
||||
iq_width = 9;
|
||||
iq_width_prach = 9;
|
||||
};
|
||||
prach_config = {
|
||||
eAxC_offset = 4;
|
||||
};
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user