Commit 9126e3dd authored by Robert Schmidt's avatar Robert Schmidt

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
parents 72f7d040 d97249d2
......@@ -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
......
add_subdirectory(utils)
configure_file(oai_version.h.in oai_version.h @ONLY)
/*
* 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:
......
......@@ -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
......
......@@ -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
......
......@@ -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;
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -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);
......
/*
* 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)
/*
* 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;
......
This diff is collapsed.
......@@ -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;
}
......
......@@ -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;
......
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;
};
});
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment