Merge branch 'integration_2023_w28' into 'develop'
integration_2023_w28 See merge request oai/openairinterface5g!2232 * !2190 Reduce compilation time of OAI using ccache * !2209 T: don't use execute_process, integrate in cmake * !2210 only cleaning, not change * !2219 NR UE decode other SI * !2223 Fix rfsimulator build * !2225 Add XnAP ASN.1 definitions * !2131 Polar coding according to the standard * !2160 Add memory sanitizer flag to build_oai and fix some bugs * !2206 Bugfix tx rf burst * !2227 Remove commented code, fix CI issues
This commit is contained in:
+46
-64
@@ -31,6 +31,25 @@ set (OPENAIR_DIR ${CMAKE_SOURCE_DIR})
|
||||
|
||||
include("cmake_targets/macros.cmake")
|
||||
|
||||
##############################
|
||||
### CCache: reduce compilation time
|
||||
##############################
|
||||
#use ccache if available
|
||||
option(CCACHE_ACTIVE "CCache" ON)
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if(CCACHE_FOUND AND CCACHE_ACTIVE)
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.4.0")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
||||
message(STATUS "Found ccache in ${CCACHE_FOUND}. Using ccache. CMake < 3.4")
|
||||
else()
|
||||
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_FOUND}")
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_FOUND}")
|
||||
message(STATUS "Found ccache in ${CCACHE_FOUND}. Using ccache. CMake >= 3.4")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Ccache not found. Consider installing it for faster compilation. Command: sudo apt/dnf install ccache")
|
||||
endif()
|
||||
|
||||
# System packages that are required
|
||||
# We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/
|
||||
# or cmake provide a generic interface to pkg-config that widely used
|
||||
@@ -170,6 +189,18 @@ if (SANITIZE_UNDEFINED)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
|
||||
endif ()
|
||||
|
||||
add_boolean_option(SANITIZE_MEMORY False "enable the memory sanitizer (MSan, requires clang, incompatible with ASan/UBSan)" ON)
|
||||
if(SANITIZE_MEMORY)
|
||||
if (SANITIZE_UNDEFINED OR SANITIZE_ADDRESS)
|
||||
message(FATAL_ERROR "memory sanitizer cannot coexist with address sanitizer or undefined behavior sanitizer, please disable either MSan or ASan and UBSan")
|
||||
endif()
|
||||
if (NOT CMAKE_C_COMPILER_ID STREQUAL "Clang" OR NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang" )
|
||||
message(FATAL_ERROR "memory sanitizer requires clang, please set clang using CC=/usr/bin/clang CXX=/usr/bin/clang++ ./build_oai ...")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize-recover=memory")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fsanitize-recover=memory")
|
||||
endif()
|
||||
|
||||
add_definitions("-DASN_DISABLE_OER_SUPPORT -DHAVE_CONFIG_H -DHAVE_CONFIG_H_")
|
||||
|
||||
#########################
|
||||
@@ -388,7 +419,6 @@ add_library(x2ap
|
||||
target_link_libraries(x2ap PUBLIC asn1_x2ap)
|
||||
target_link_libraries(x2ap PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
|
||||
|
||||
# F1AP
|
||||
##############
|
||||
set(F1AP_DIR ${OPENAIR2_DIR}/F1AP)
|
||||
@@ -578,6 +608,15 @@ include_directories("${OPENAIR_DIR}")
|
||||
# Utilities
|
||||
###############
|
||||
|
||||
# include T directory even if the T is off because T macros are in the code
|
||||
# no matter what. Note: sone files are generated, so we have both source and
|
||||
# binary directories
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common/utils/T
|
||||
${CMAKE_CURRENT_BINARY_DIR}/common/utils/T)
|
||||
|
||||
# set the T_LIB name to T if the target exists, otherwise leave empty
|
||||
set(T_LIB $<TARGET_NAME_IF_EXISTS:T>)
|
||||
|
||||
add_library(HASHTABLE
|
||||
${OPENAIR_DIR}/common/utils/hashtable/hashtable.c
|
||||
${OPENAIR_DIR}/common/utils/hashtable/obj_hashtable.c
|
||||
@@ -595,6 +634,7 @@ add_library(UTIL
|
||||
${OPENAIR_DIR}/common/utils/time_meas.c
|
||||
${OPENAIR_DIR}/common/utils/time_stat.c
|
||||
)
|
||||
target_link_libraries(UTIL PUBLIC ${T_LIB})
|
||||
|
||||
set(SECURITY_SRC
|
||||
${OPENAIR3_DIR}/SECU/secu_defs.c
|
||||
@@ -1127,8 +1167,6 @@ set(PHY_MEX_UE
|
||||
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ue_measurements.c
|
||||
${OPENAIR_DIR}/common/utils/LOG/log.c
|
||||
${OPENAIR_DIR}/common/utils/T/T.c
|
||||
${OPENAIR_DIR}/common/utils/T/local_tracer.c
|
||||
)
|
||||
add_library(PHY_MEX ${PHY_MEX_UE})
|
||||
target_link_libraries(PHY_MEX PRIVATE asn1_lte_rrc_hdrs)
|
||||
@@ -1882,51 +1920,12 @@ add_library(oai_iqplayer MODULE
|
||||
)
|
||||
set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}")
|
||||
|
||||
#include T directory even if the T is off because T macros are in the code
|
||||
#no matter what
|
||||
include_directories("${OPENAIR_DIR}/common/utils/T")
|
||||
|
||||
if (${T_TRACER})
|
||||
set(T_SOURCE
|
||||
${OPENAIR_DIR}/common/utils/T/T_IDs.h
|
||||
${OPENAIR_DIR}/common/utils/T/T.c
|
||||
${OPENAIR_DIR}/common/utils/T/local_tracer.c)
|
||||
set(T_LIB "rt")
|
||||
endif (${T_TRACER})
|
||||
|
||||
#Some files in the T directory are generated.
|
||||
#This rule and the following deal with it.
|
||||
add_custom_command (
|
||||
OUTPUT ${OPENAIR_DIR}/common/utils/T/T_IDs.h
|
||||
COMMAND make check_vcd
|
||||
WORKING_DIRECTORY ${OPENAIR_DIR}/common/utils/T
|
||||
DEPENDS ${OPENAIR_DIR}/common/utils/T/T_messages.txt
|
||||
${OPENAIR_DIR}/common/utils/LOG/vcd_signal_dumper.c
|
||||
${OPENAIR_DIR}/common/utils/LOG/vcd_signal_dumper.h
|
||||
)
|
||||
|
||||
execute_process (
|
||||
COMMAND make check_vcd
|
||||
WORKING_DIRECTORY ${OPENAIR_DIR}/common/utils/T
|
||||
)
|
||||
#This rule is specifically needed to generate T files
|
||||
#before anything else in a project that uses the T.
|
||||
#See below, there are some 'add_dependencies' showing that.
|
||||
#Basically we create a custom target and we make other
|
||||
#targets depend on it. That forces cmake to generate
|
||||
#T files before anything else.
|
||||
add_custom_target (
|
||||
generate_T
|
||||
DEPENDS ${OPENAIR_DIR}/common/utils/T/T_IDs.h
|
||||
)
|
||||
|
||||
#################################
|
||||
# add executables for operation
|
||||
#################################
|
||||
add_library(minimal_lib
|
||||
${OPENAIR_DIR}/common/utils/LOG/log.c
|
||||
${OPENAIR_DIR}/common/utils/minimal_stub.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
target_link_libraries(minimal_lib pthread dl ${T_LIB})
|
||||
|
||||
@@ -1965,7 +1964,6 @@ add_executable(lte-softmodem
|
||||
${OPENAIR_DIR}/common/utils/lte/ue_power.c
|
||||
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
add_dependencies(lte-softmodem oai_iqplayer)
|
||||
|
||||
@@ -1992,7 +1990,6 @@ add_executable(oairu
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
${OPENAIR_DIR}/openair1/SCHED/phy_procedures_lte_common.c
|
||||
${OPENAIR_DIR}/executables/main_ru.c
|
||||
${T_SOURCE}
|
||||
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
|
||||
)
|
||||
target_link_libraries(oairu PRIVATE
|
||||
@@ -2024,7 +2021,6 @@ add_executable(lte-uesoftmodem
|
||||
${OPENAIR_DIR}/common/utils/lte/ue_power.c
|
||||
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
|
||||
if (NOT ${NOS1})
|
||||
@@ -2067,7 +2063,6 @@ add_executable(nr-softmodem
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
|
||||
target_link_libraries(nr-softmodem PRIVATE
|
||||
@@ -2104,13 +2099,12 @@ add_executable(nr-cuup
|
||||
${OPENAIR2_DIR}/E1AP/e1ap_setup.c
|
||||
${NR_PDCP_SRC}
|
||||
${NR_SDAP_SRC}
|
||||
${T_SOURCE}
|
||||
)
|
||||
|
||||
target_link_libraries(nr-cuup PRIVATE
|
||||
CONFIG_LIB ITTI SCTP_CLIENT
|
||||
GTPV1U e1ap e1_pdcp_if f1ap SIMU_ETH
|
||||
z sctp dl pthread shlib_loader)
|
||||
z sctp dl pthread shlib_loader ${T_LIB})
|
||||
target_link_libraries(nr-cuup PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
|
||||
# nr-uesoftmodem is UE implementation
|
||||
@@ -2131,7 +2125,6 @@ add_executable(nr-uesoftmodem
|
||||
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
|
||||
target_link_libraries(nr-uesoftmodem PRIVATE
|
||||
@@ -2168,7 +2161,6 @@ target_link_libraries(nr-uesoftmodem PRIVATE
|
||||
add_executable(dlsim_tm4
|
||||
${OPENAIR1_DIR}/SIMULATION/LTE_PHY/dlsim_tm4.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/lte_phy_scope_tm4.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
target_link_libraries (dlsim_tm4
|
||||
-Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB PHY ITTI -Wl,--end-group
|
||||
@@ -2187,29 +2179,26 @@ target_link_libraries(rftest PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
add_executable(polartest
|
||||
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
target_link_libraries(polartest PRIVATE
|
||||
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE CONFIG_LIB -Wl,--end-group
|
||||
m pthread dl
|
||||
m pthread dl ${T_LIB}
|
||||
)
|
||||
|
||||
add_executable(smallblocktest
|
||||
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/smallblocktest.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
|
||||
target_link_libraries(smallblocktest PRIVATE
|
||||
-Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON -Wl,--end-group
|
||||
m pthread dl shlib_loader
|
||||
m pthread dl shlib_loader ${T_LIB}
|
||||
)
|
||||
|
||||
|
||||
add_executable(ldpctest
|
||||
${PHY_NR_CODINGIF}
|
||||
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
|
||||
add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc ldpc_parityCheck)
|
||||
@@ -2218,14 +2207,13 @@ if (ENABLE_LDPC_CUDA)
|
||||
endif()
|
||||
target_link_libraries(ldpctest PRIVATE
|
||||
-Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON -Wl,--end-group
|
||||
m pthread dl shlib_loader
|
||||
m pthread dl shlib_loader ${T_LIB}
|
||||
)
|
||||
|
||||
add_executable(nr_dlschsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
target_link_libraries(nr_dlschsim PRIVATE
|
||||
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
|
||||
@@ -2237,7 +2225,6 @@ add_executable(nr_pbchsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
target_link_libraries(nr_pbchsim PRIVATE
|
||||
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
|
||||
@@ -2251,7 +2238,6 @@ add_executable(nr_pucchsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/pucchsim.c
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
target_link_libraries(nr_pucchsim PRIVATE
|
||||
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
|
||||
@@ -2269,7 +2255,6 @@ add_executable(nr_dlsim
|
||||
${NFAPI_USER_DIR}/nfapi.c
|
||||
${NFAPI_USER_DIR}/gnb_ind_vars.c
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
target_link_libraries(nr_dlsim PRIVATE
|
||||
-Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group
|
||||
@@ -2281,7 +2266,6 @@ add_executable(nr_prachsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/prachsim.c
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
target_link_libraries(nr_prachsim PRIVATE
|
||||
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB CONFIG_LIB -lz -Wl,--end-group
|
||||
@@ -2293,7 +2277,6 @@ add_executable(nr_ulschsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
target_link_libraries(nr_ulschsim PRIVATE
|
||||
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
|
||||
@@ -2311,7 +2294,6 @@ add_executable(nr_ulsim
|
||||
${NFAPI_USER_DIR}/nfapi.c
|
||||
${NFAPI_USER_DIR}/gnb_ind_vars.c
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
|
||||
if (ENABLE_LDPC_T1)
|
||||
@@ -2331,7 +2313,6 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
|
||||
${OPENAIR_DIR}/common/utils/lte/ue_power.c
|
||||
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
|
||||
${OPENAIR1_DIR}/PHY/INIT/lte_param_init.c
|
||||
${T_SOURCE}
|
||||
${NFAPI_USER_DIR}/nfapi.c
|
||||
)
|
||||
target_link_libraries (${myExe} PRIVATE
|
||||
@@ -2380,6 +2361,7 @@ if (${T_TRACER})
|
||||
oai_eth_transpro oai_mobipass coding HASHTABLE UTIL OMG_SUMO
|
||||
SECURITY SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL
|
||||
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB
|
||||
MISC_NFAPI_LTE_LIB MISC_NFAPI_NR_LIB
|
||||
PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX
|
||||
L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR ngap
|
||||
CN_UTILS GTPV1U SCTP_CLIENT MME_APP LIB_NAS_UE NB_IoT SIMU SIMU_ETH OPENAIR0_LIB
|
||||
|
||||
+15
-1
@@ -155,6 +155,10 @@ Options:
|
||||
Enable the address sanitizer on all targets
|
||||
--sanitize-undefined | -fsanitize=undefined
|
||||
Enable the undefined behavior sanitizer on all targets
|
||||
--sanitize-memory | -fsanitize=memory
|
||||
Enable the memory sanitizer on all targets. Requires clang, and is
|
||||
incompatible with ASan/UBSan. To build, issue:
|
||||
CC=/usr/bin/clang CXX=/usr/bin/clang++ ./build_oai ... --sanitize-memory
|
||||
-h | --help
|
||||
Print this help"
|
||||
}
|
||||
@@ -269,11 +273,16 @@ function main() {
|
||||
shift;;
|
||||
-w | --hardware)
|
||||
case "$2" in
|
||||
"USRP" | "BLADERF" | "LMSSDR" | "IRIS" | "SIMU")
|
||||
"USRP" | "BLADERF" | "LMSSDR" | "IRIS")
|
||||
HW="OAI_"$2
|
||||
TARGET_LIST="$TARGET_LIST oai_${2,,}devif" # ,, makes lowercase
|
||||
CMAKE_CMD="$CMAKE_CMD -DOAI_$2=ON"
|
||||
;;
|
||||
"SIMU")
|
||||
HW="OAI_"$2
|
||||
TARGET_LIST="$TARGET_LIST rfsimulator"
|
||||
CMAKE_CMD="$CMAKE_CMD -DOAI_$2=ON"
|
||||
;;
|
||||
"AW2SORI")
|
||||
HW="OAI_"$2
|
||||
TARGET_LIST="$TARGET_LIST aw2sori_transpro"
|
||||
@@ -402,6 +411,11 @@ function main() {
|
||||
--sanitize-undefined | -fundefined=address)
|
||||
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_UNDEFINED=True"
|
||||
shift;;
|
||||
--sanitize-memory | -fsanitize=memory)
|
||||
echo_warning "Note: memory sanitizer\n* requires clang (tested: v17)\n* is incompatible with address/undefined behavior sanitizer\n* requires cmake_targets/tools/memsan.patch"
|
||||
sleep 2
|
||||
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_MEMORY=ON -DSANITIZE_ADDRESS=OFF -DSANITIZE_UNDEFINED=OFF"
|
||||
shift;;
|
||||
-h | --help)
|
||||
print_help
|
||||
exit 1;;
|
||||
|
||||
@@ -103,6 +103,7 @@ get_distribution_release() {
|
||||
check_supported_distribution() {
|
||||
local distribution=$(get_distribution_release)
|
||||
case "$distribution" in
|
||||
"ubuntu23.10") return 0 ;;
|
||||
"ubuntu22.04") return 0 ;;
|
||||
"ubuntu21.04") return 0 ;;
|
||||
"ubuntu20.04") return 0 ;;
|
||||
@@ -618,6 +619,7 @@ check_install_oai_software() {
|
||||
libsctp-dev \
|
||||
libssl-dev \
|
||||
libtool \
|
||||
libxft-dev \
|
||||
patch \
|
||||
openssl \
|
||||
zlib1g-dev \
|
||||
@@ -647,6 +649,7 @@ check_install_oai_software() {
|
||||
lksctp-tools \
|
||||
lksctp-tools-devel \
|
||||
libtool \
|
||||
libXft-devel \
|
||||
ninja-build \
|
||||
make \
|
||||
openssl \
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
commit bf7f0c4f0f1bfce586667b50050640b67a7a747a
|
||||
Author: Robert Schmidt <robert.schmidt@openairinterface.org>
|
||||
Date: Wed Jun 7 18:24:50 2023 +0200
|
||||
|
||||
Fix dlopen() linker errors in dfts, ldpc, ldpc_parityCheck, and params_libconfig
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index c29105d503..3b9e7d1246 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -508,7 +508,7 @@ add_library(CONFIG_LIB
|
||||
)
|
||||
target_link_libraries(CONFIG_LIB PRIVATE dl UTIL)
|
||||
add_library(params_libconfig MODULE ${CONFIG_ROOTDIR}/libconfig/config_libconfig.c)
|
||||
-target_link_libraries(params_libconfig config)
|
||||
+target_link_libraries(params_libconfig config CONFIG_LIB minimal_lib)
|
||||
# shared library loader
|
||||
set (SHLIB_LOADER_SOURCES
|
||||
${OPENAIR_DIR}/common/utils/load_module_shlib.c
|
||||
@@ -1018,16 +1018,19 @@ if (ENABLE_LDPC_CUDA)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
-add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} )
|
||||
+add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} ${OPENAIR1_DIR}/PHY/CODING/crc_byte.c)
|
||||
target_link_libraries(ldpc PRIVATE ldpc_gen_HEADERS)
|
||||
+target_link_libraries(ldpc PRIVATE UTIL)
|
||||
|
||||
add_library(ldpc_parityCheck MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} )
|
||||
target_compile_definitions(ldpc_parityCheck PUBLIC NR_LDPC_ENABLE_PARITY_CHECK)
|
||||
target_link_libraries(ldpc_parityCheck PRIVATE ldpc_gen_HEADERS)
|
||||
+target_link_libraries(ldpc_parityCheck PRIVATE UTIL minimal_lib)
|
||||
|
||||
add_library(coding MODULE ${PHY_TURBOSRC} )
|
||||
|
||||
add_library(dfts MODULE ${OPENAIR1_DIR}/PHY/TOOLS/oai_dfts.c )
|
||||
+target_link_libraries(dfts PRIVATE minimal_lib)
|
||||
|
||||
|
||||
set(PHY_SRC_COMMON
|
||||
diff --git a/common/utils/minimal_stub.c b/common/utils/minimal_stub.c
|
||||
index be9c1b399d..7ad0df4d56 100644
|
||||
--- a/common/utils/minimal_stub.c
|
||||
+++ b/common/utils/minimal_stub.c
|
||||
@@ -1,6 +1,8 @@
|
||||
+#include <stdlib.h>
|
||||
#ifndef T_TRACER
|
||||
int T_stdout;
|
||||
#endif
|
||||
+int oai_exit = 0;
|
||||
|
||||
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
|
||||
{
|
||||
@@ -8,3 +8,4 @@ if(ENABLE_WEBSRV)
|
||||
add_subdirectory(websrv)
|
||||
endif()
|
||||
|
||||
add_subdirectory(T)
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include "T.h"
|
||||
#include <common/utils/utils.h>
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#include <assert.h>
|
||||
@@ -414,6 +413,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
|
||||
#define LOG_F LOG_I /* because LOG_F was originaly to dump a message or buffer but is also used as a regular level...., to dump use LOG_DUMPMSG */
|
||||
|
||||
# if T_TRACER
|
||||
#include "T.h"
|
||||
/* per component, level dependent macros */
|
||||
# define LOG_E(c, x...) do { T(T_LEGACY_ ## c ## _ERROR, T_PRINTF(x)) ; if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_ERR ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ;} } while (0)
|
||||
# define LOG_W(c, x...) do { T(T_LEGACY_ ## c ## _WARNING, T_PRINTF(x)); if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_WARNING ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ;} } while (0)
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
add_executable(genids genids.c)
|
||||
set_target_properties(genids PROPERTIES RUNTIME_OUTPUT_DIRECTORY .)
|
||||
|
||||
add_custom_command(OUTPUT T_IDs.h
|
||||
COMMAND ./genids ${CMAKE_CURRENT_SOURCE_DIR}/T_messages.txt T_IDs.h
|
||||
DEPENDS genids
|
||||
COMMENT "Generating T_IDs.h from T_messages.txt"
|
||||
)
|
||||
add_custom_command(OUTPUT T_messages.txt.h
|
||||
COMMAND xxd -i T_messages.txt ${CMAKE_CURRENT_BINARY_DIR}/T_messages.txt.h
|
||||
COMMENT "Generating T_messages.txt.h from T_messages.txt"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
add_executable(_check_vcd check_vcd.c tracer/database.c tracer/utils.c T_IDs.h T_messages.txt.h)
|
||||
target_include_directories(_check_vcd PRIVATE
|
||||
.. ../itti ../../../openair2/COMMON tracer
|
||||
${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_compile_options(_check_vcd PRIVATE -Wall)
|
||||
target_link_libraries(_check_vcd PRIVATE m pthread)
|
||||
set_target_properties(_check_vcd PROPERTIES RUNTIME_OUTPUT_DIRECTORY .)
|
||||
|
||||
add_custom_target(check_vcd
|
||||
COMMAND _check_vcd ${CMAKE_CURRENT_SOURCE_DIR}/T_messages.txt ${CMAKE_CURRENT_SOURCE_DIR}/../LOG/vcd_signal_dumper.h
|
||||
DEPENDS _check_vcd
|
||||
COMMENT "Checking validity of VCD files"
|
||||
)
|
||||
|
||||
# This rule is specifically needed to generate T files before anything else in
|
||||
# a project that uses the T.
|
||||
# See root CMakeLists.txt, there are some 'add_dependencies' showing that.
|
||||
# Basically we create a custom target and we make other targets depend on it.
|
||||
# That forces cmake to generate T files before anything else.
|
||||
add_custom_target(generate_T DEPENDS T_IDs.h check_vcd)
|
||||
|
||||
# even if T is off, we need the headers as many targets depend on it
|
||||
# for this, create an INTERFACE (header-only) library T_headers. To ensure the
|
||||
# headers have really been created, we make this headers library explicitly
|
||||
# depend on the generated headers.
|
||||
add_library(T_headers INTERFACE)
|
||||
add_dependencies(T_headers T_IDs.h T_messages.txt.h)
|
||||
target_include_directories(T_headers INTERFACE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
if(T_TRACER)
|
||||
add_library(T STATIC T.c local_tracer.c T_IDs.h T_messages.txt.h)
|
||||
target_link_libraries(T PUBLIC rt)
|
||||
target_link_libraries(T PRIVATE CONFIG_LIB T_headers)
|
||||
|
||||
add_subdirectory(tracer)
|
||||
endif()
|
||||
@@ -0,0 +1,20 @@
|
||||
# T tracer
|
||||
|
||||
The T tracer is sort of a *framework* to debug and monitor the softmodem.
|
||||
|
||||
It is made of two main parts:
|
||||
|
||||
* an events' collector integrated to the real-time processing,
|
||||
* a separate set of programs to receive, record, display, replay and
|
||||
analyse the events sent by the collector.
|
||||
|
||||
## Documentation
|
||||
|
||||
* [Basic usage](./T/basic.md)
|
||||
* [Record](./T/record.md)
|
||||
* [Replay](./T/replay.md)
|
||||
* [Multiple tracers](./T/multi.md)
|
||||
* [MAC PDUs and wireshark](./T/wireshark.md)
|
||||
* [The *enb* tracer](./T/enb.md)
|
||||
* [The *to_vcd* tracer](./T/to_vcd.md)
|
||||
* [Tutorial: how to create a new trace](./T/howto_new_trace.md)
|
||||
@@ -0,0 +1,90 @@
|
||||
# Basic usage of the T
|
||||
|
||||
## Compilation
|
||||
|
||||
### softmodem side
|
||||
|
||||
Simply call `build_oai` the usual way, for example `./build_oai --eNB -w USRP`.
|
||||
The T tracer is compiled in by default.
|
||||
|
||||
### tracer side
|
||||
|
||||
Go to the directory `common/utils/T/tracer` and do `make`. This will locally
|
||||
compile all tracer executables, and place them in `common/utils/T/tracer`. If
|
||||
you wish to keep source and build separate, go to your existing build directory
|
||||
(typically `cmake_targets/ran_build/build`), and do `make T_tools` (or `ninja
|
||||
T_tools`). After that, the executables will be in
|
||||
`<build-dir>/common/utils/T/tracer`.
|
||||
|
||||
In case of failure with one of the following errors:
|
||||
|
||||
```shell
|
||||
/usr/bin/ld: cannot find -lXft
|
||||
```
|
||||
or
|
||||
```shell
|
||||
-- Checking for module 'xft'
|
||||
-- No package 'xft' found
|
||||
CMake Error at /usr/share/cmake-3.16/Modules/FindPkgConfig.cmake:463 (message):
|
||||
A required package was not found
|
||||
```
|
||||
Run:
|
||||
|
||||
```shell
|
||||
sudo apt-get install libxft-dev
|
||||
```
|
||||
|
||||
## Run the softmodem
|
||||
|
||||
Run the softmodem with the option `--T_stdout 2` and it will wait for a
|
||||
tracer to connect to it before processing. (This option is confusing
|
||||
and may change in the future.)
|
||||
|
||||
```shell
|
||||
cd cmake_targets/ran_build/build
|
||||
sudo ./lte-softmodem -O [configuration file] --T_stdout 2
|
||||
```
|
||||
|
||||
Additional options can be passed to the softmodem.
|
||||
|
||||
The option `--T_nowait` lets the processing start immediately without
|
||||
first waiting for a tracer.
|
||||
|
||||
The option `--T_port [port]` changes the default port used by the
|
||||
softmodem to wait for a tracer. The default port is 2021.
|
||||
|
||||
The option `--T_dont_fork` allows one to use gdb to debug problems
|
||||
with the softmodem. Note that you then may have some "zombie"
|
||||
processes after crashes, in which case you can run
|
||||
`sudo killall -9 lte-softmodem` to get rid of them (`lte-softmodem`
|
||||
to be replaced by the program you trace, like `lte-softmodem-nos1`
|
||||
or `oaisim`).
|
||||
|
||||
The option `--T_stdout` also accepts values 0 (to disable output
|
||||
on the terminal and only use the T tracer) and 1 (to disable
|
||||
the T tracer and only output on the terminal). The default is
|
||||
1.
|
||||
|
||||
## Run a tracer
|
||||
|
||||
Go into the directory `common/utils/T/tracer` (or
|
||||
`cmake_targets/ran_build/build/common/utils/T/tracer`) and run for example the
|
||||
`enb` tracer:
|
||||
|
||||
```shell
|
||||
./enb -d ../T_messages.txt
|
||||
```
|
||||
|
||||
To trace a remote program, use the `-ip` option. For example,
|
||||
if you want to trace a program running on `192.168.12.148` do:
|
||||
|
||||
```shell
|
||||
./enb -d ../T_messages.txt -ip 192.168.12.148
|
||||
```
|
||||
|
||||
A graphical user interface will appear with which you can interact to
|
||||
control the monitoring. See [there](./enb.md) for more documentation
|
||||
about the `enb` tracer.
|
||||
|
||||
It is possible to run several tracers at the same time. See
|
||||
[here](./multi.md).
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||

|
||||
[source file of this image](./enb_trace.odp)
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 144 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 303 KiB |
@@ -0,0 +1,95 @@
|
||||
# T tracer - a simple tutorial
|
||||
|
||||
There is a diff file with all modifications:
|
||||
[howto_new_trace.patch](./howto_new_trace.patch).
|
||||
We use tag 2023.w28
|
||||
To use the patch, clone the repository,
|
||||
then in the top directory of openairinterface:
|
||||
```
|
||||
git checkout 2023.w28
|
||||
patch -p1 < common/utils/T/DOC/T/howto_new_trace.patch
|
||||
```
|
||||
|
||||
Then compile nr-softmodem as usual.
|
||||
|
||||
## 1 - create a new trace
|
||||
|
||||
As an example, let's add a new trace to dump LDPC decoding success.
|
||||
|
||||
In the file `common/utils/T/T_messages.txt`
|
||||
we add those two lines:
|
||||
|
||||
```
|
||||
ID = LDPC_OK
|
||||
FORMAT = int,segment : int,nb_segments : int,offset : buffer,data
|
||||
```
|
||||
|
||||
- You create an ID for the new trace.
|
||||
- You give the format as a list of variables with there types.
|
||||
|
||||
Then, in the file `openair1/SCHED_NR/phy_procedures_nr_gNB.c`,
|
||||
in function `nr_postDecode()`, we add, at the place where we want to trace:
|
||||
|
||||
```
|
||||
T(T_LDPC_OK,
|
||||
T_INT(rdata->segment_r),
|
||||
T_INT(rdata->nbSegments),
|
||||
T_INT(rdata->offset),
|
||||
T_BUFFER(ulsch_harq->c[r], rdata->Kr_bytes - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0)));
|
||||
```
|
||||
|
||||
And that's all, the code is instrumented, a trace is created,
|
||||
we now need a tracer to process the trace.
|
||||
|
||||
## 2. create a tracer
|
||||
|
||||
See `trace_ldpc.c` in the attached diff. Read it, there is documentation.
|
||||
To compile, just do `make trace_ldpc` in `common/utils/T/tracer`
|
||||
To use: `cd common/utils/T/tracer; ./trace_ldpc -d ../T_messages.txt`
|
||||
|
||||
Your tracer can do whatever it wants with the data.
|
||||
|
||||
The Makefile has been modified to compile it. See the diff.
|
||||
|
||||
Use it as a basis for your own tracer.
|
||||
You can also look at the other tracers, especially `textlog.c`
|
||||
and `macpdu2wireshark.c` which are the most useful for me to
|
||||
trace/debug the nr-softmodem.
|
||||
|
||||
## 3. available types in a trace
|
||||
|
||||
You trace the code with:
|
||||
|
||||
```
|
||||
T(T_trace_name, T_xxx(variable1), T_xxx(variables2), ...);
|
||||
```
|
||||
|
||||
`T_xxx` can be:
|
||||
|
||||
- `T_INT(variable)`
|
||||
- `T_FLOAT(variable)` (not tested much, may fail)
|
||||
- `T_BUFFER(variable, length)`
|
||||
- `T_STRING(variable)`
|
||||
- `T_PRINTF(format, arg1, ... argn)`
|
||||
|
||||
What is traced is obvious from the name. `T_INT` traces an int for example.
|
||||
|
||||
corresponding type to put in `T_messages.txt`
|
||||
|
||||
- `T_INT`: int
|
||||
- `T_FLOAT`: float
|
||||
- `T_BUFFER`: buffer
|
||||
- `T_STRING`: string
|
||||
- `T_PRINTF`: string
|
||||
|
||||
And that's all.
|
||||
You can add as many traces as you want, just add them in `T_messages.txt`,
|
||||
put the `T()` macro in the code where you want to trace, and modify your
|
||||
tracer to deal with it.
|
||||
|
||||
An alternative to writing your own tracer could be to use `textlog`
|
||||
with `-full` command line and process the text with some external
|
||||
tools.
|
||||
|
||||
It is also possible to record the events in a file using the tracer
|
||||
`record` and then use `replay` to process the recorded file later.
|
||||
@@ -0,0 +1,210 @@
|
||||
diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt
|
||||
index c535f36f5e..1632131ceb 100644
|
||||
--- a/common/utils/T/T_messages.txt
|
||||
+++ b/common/utils/T/T_messages.txt
|
||||
@@ -4,6 +4,9 @@ ID = ENB_MASTER_TICK
|
||||
GROUP = ALL:GENERAL:ENB
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe
|
||||
|
||||
+ID = LDPC_OK
|
||||
+ FORMAT = int,segment : int,nb_segments : int,offset : buffer,data
|
||||
+
|
||||
#PHY logs
|
||||
ID = ENB_PHY_UL_TICK
|
||||
DESC = eNodeB uplink tick - one tick per ms at start of uplink processing
|
||||
diff --git a/common/utils/T/tracer/CMakeLists.txt b/common/utils/T/tracer/CMakeLists.txt
|
||||
index 02e0e2dc9b..db438c42d3 100644
|
||||
--- a/common/utils/T/tracer/CMakeLists.txt
|
||||
+++ b/common/utils/T/tracer/CMakeLists.txt
|
||||
@@ -57,6 +57,10 @@ target_link_libraries(gnb PRIVATE tracer_utils tracer_filter tracer_gui
|
||||
tracer_logger tracer_view tracer_events)
|
||||
target_link_libraries(gnb PRIVATE png)
|
||||
|
||||
+add_executable(trace_ldpc trace_ldpc.c)
|
||||
+target_link_libraries(trace_ldpc PRIVATE tracer_utils tracer_filter
|
||||
+ tracer_logger tracer_view)
|
||||
+
|
||||
add_subdirectory(filter)
|
||||
add_subdirectory(gui)
|
||||
add_subdirectory(logger)
|
||||
@@ -66,4 +70,4 @@ add_custom_target(T_tools)
|
||||
add_dependencies(T_tools
|
||||
record replay extract_config textlog enb ue vcd macpdu2wireshark
|
||||
extract_input_subframe extract_output_subframe to_vcd extract multi
|
||||
- gnb)
|
||||
+ gnb trace_ldpc)
|
||||
diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile
|
||||
index d3c959a689..d13ff1e996 100644
|
||||
--- a/common/utils/T/tracer/Makefile
|
||||
+++ b/common/utils/T/tracer/Makefile
|
||||
@@ -7,4 +7,4 @@ clean:
|
||||
rm -rf tracer_build
|
||||
rm record replay extract_config textlog enb ue vcd macpdu2wireshark \
|
||||
extract_input_subframe extract_output_subframe to_vcd extract multi \
|
||||
- gnb
|
||||
+ gnb trace_ldpc
|
||||
diff --git a/common/utils/T/tracer/trace_ldpc.c b/common/utils/T/tracer/trace_ldpc.c
|
||||
new file mode 100644
|
||||
index 0000000000..00baf34774
|
||||
--- /dev/null
|
||||
+++ b/common/utils/T/tracer/trace_ldpc.c
|
||||
@@ -0,0 +1,143 @@
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <pthread.h>
|
||||
+#include <signal.h>
|
||||
+#include "database.h"
|
||||
+#include "event.h"
|
||||
+#include "handler.h"
|
||||
+#include "logger/logger.h"
|
||||
+#include "utils.h"
|
||||
+#include "event_selector.h"
|
||||
+#include "config.h"
|
||||
+
|
||||
+/* this function sends the activated traces to the nr-softmodem */
|
||||
+void activate_traces(int socket, int number_of_events, int *is_on)
|
||||
+{
|
||||
+ char t = 1;
|
||||
+ if (socket_send(socket, &t, 1) == -1 ||
|
||||
+ socket_send(socket, &number_of_events, sizeof(int)) == -1 ||
|
||||
+ socket_send(socket, is_on, number_of_events * sizeof(int)) == -1)
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+void usage(void)
|
||||
+{
|
||||
+ printf(
|
||||
+"options:\n"
|
||||
+" -d <database file> this option is mandatory\n"
|
||||
+" -ip <host> connect to given IP address (default %s)\n"
|
||||
+" -p <port> connect to given port (default %d)\n",
|
||||
+ DEFAULT_REMOTE_IP,
|
||||
+ DEFAULT_REMOTE_PORT
|
||||
+ );
|
||||
+ exit(1);
|
||||
+}
|
||||
+
|
||||
+int main(int n, char **v)
|
||||
+{
|
||||
+ char *database_filename = NULL;
|
||||
+ void *database;
|
||||
+ char *ip = DEFAULT_REMOTE_IP;
|
||||
+ int port = DEFAULT_REMOTE_PORT;
|
||||
+ int *is_on;
|
||||
+ int number_of_events;
|
||||
+ int i;
|
||||
+ int socket;
|
||||
+ int ldpc_ok_id;
|
||||
+ database_event_format f;
|
||||
+ int segment;
|
||||
+ int nb_segments;
|
||||
+ int offset;
|
||||
+ int data;
|
||||
+
|
||||
+ /* write on a socket fails if the other end is closed and we get SIGPIPE */
|
||||
+ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort();
|
||||
+
|
||||
+ /* parse command line options */
|
||||
+ for (i = 1; i < n; i++) {
|
||||
+ if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
|
||||
+ if (!strcmp(v[i], "-d"))
|
||||
+ { if (i > n-2) usage(); database_filename = v[++i]; continue; }
|
||||
+ if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; }
|
||||
+ if (!strcmp(v[i], "-p"))
|
||||
+ { if (i > n-2) usage(); port = atoi(v[++i]); continue; }
|
||||
+ usage();
|
||||
+ }
|
||||
+
|
||||
+ if (database_filename == NULL) {
|
||||
+ printf("ERROR: provide a database file (-d)\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ /* load the database T_messages.txt */
|
||||
+ database = parse_database(database_filename);
|
||||
+ load_config_file(database_filename);
|
||||
+
|
||||
+ /* an array of int for all the events defined in the database is needed */
|
||||
+ number_of_events = number_of_ids(database);
|
||||
+ is_on = calloc(number_of_events, sizeof(int));
|
||||
+ if (is_on == NULL) abort();
|
||||
+
|
||||
+ /* activate the LDPC_OK trace in this array */
|
||||
+ on_off(database, "LDPC_OK", is_on, 1);
|
||||
+
|
||||
+ /* connect to the nr-softmodem */
|
||||
+ socket = connect_to(ip, port);
|
||||
+
|
||||
+ /* activate the trace LDPC_OK in the nr-softmodem */
|
||||
+ activate_traces(socket, number_of_events, is_on);
|
||||
+
|
||||
+ free(is_on);
|
||||
+
|
||||
+ /* get the format of the LDPC_OK trace */
|
||||
+ ldpc_ok_id = event_id_from_name(database, "LDPC_OK");
|
||||
+ f = get_format(database, ldpc_ok_id);
|
||||
+
|
||||
+/* this macro looks for a particular element and checks its type */
|
||||
+#define G(var_name, var_type, var) \
|
||||
+ if (!strcmp(f.name[i], var_name)) { \
|
||||
+ if (strcmp(f.type[i], var_type)) { printf("bad type for %s\n", var_name); exit(1); } \
|
||||
+ var = i; \
|
||||
+ continue; \
|
||||
+ }
|
||||
+
|
||||
+ /* get the elements of the LDPC_OK trace
|
||||
+ * the value is an index in the event, see below
|
||||
+ */
|
||||
+ for (i = 0; i < f.count; i++) {
|
||||
+ G("segment", "int", segment);
|
||||
+ G("nb_segments", "int", nb_segments);
|
||||
+ G("offset", "int", offset);
|
||||
+ G("data", "buffer", data);
|
||||
+ }
|
||||
+
|
||||
+ /* a buffer needed to receive events from the nr-softmodem */
|
||||
+ OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
|
||||
+
|
||||
+ /* read events */
|
||||
+ while (1) {
|
||||
+ event e;
|
||||
+ e = get_event(socket, &ebuf, database);
|
||||
+ if (e.type == -1) break;
|
||||
+ if (e.type == ldpc_ok_id) {
|
||||
+ /* this is how to access the elements of the LDPC_OK trace.
|
||||
+ * we use e.e[<element>] and then the correct suffix, here
|
||||
+ * it's .i for the integer and .b for the buffer and .bsize
|
||||
+ * for the buffer size
|
||||
+ * see in event.h the structure event_arg
|
||||
+ */
|
||||
+ unsigned char *buf = e.e[data].b;
|
||||
+ printf("get LDPC_OK event segment %d nb_segments %d offset %d buffer length %d = [",
|
||||
+ e.e[segment].i,
|
||||
+ e.e[nb_segments].i,
|
||||
+ e.e[offset].i,
|
||||
+ e.e[data].bsize);
|
||||
+ for (i = 0; i < e.e[data].bsize; i++)
|
||||
+ printf(" %2.2x", buf[i]);
|
||||
+ printf("]\n");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
|
||||
index f33106ecaa..129b3606b6 100644
|
||||
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
|
||||
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
|
||||
@@ -255,6 +255,11 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
|
||||
ulsch_harq->processedSegments,
|
||||
rdata->nbSegments);
|
||||
if (decodeSuccess) {
|
||||
+ T(T_LDPC_OK,
|
||||
+ T_INT(rdata->segment_r),
|
||||
+ T_INT(rdata->nbSegments),
|
||||
+ T_INT(rdata->offset),
|
||||
+ T_BUFFER(ulsch_harq->c[r], rdata->Kr_bytes - (ulsch_harq->F >> 3) - ((ulsch_harq->C > 1) ? 3 : 0)));
|
||||
memcpy(ulsch_harq->b + rdata->offset, ulsch_harq->c[r], rdata->Kr_bytes - (ulsch_harq->F >> 3) - ((ulsch_harq->C > 1) ? 3 : 0));
|
||||
|
||||
} else {
|
||||
@@ -0,0 +1,57 @@
|
||||
# Multiple tracers
|
||||
|
||||
To connect several tracers to the same process, first launch the `multi`
|
||||
tracer.
|
||||
|
||||
Run as:
|
||||
|
||||
```shell
|
||||
cd common/utils/T/tracer
|
||||
./multi -d ../T_messages.txt
|
||||
```
|
||||
|
||||
Then connect other tracers (`enb`, `textlog`, `to_vcd`, etc.) to the
|
||||
`multi` tracer.
|
||||
|
||||
For example (if you debug the `lte-softmodem`) in one terminal, run:
|
||||
|
||||
```shell
|
||||
cd common/utils/T/tracer
|
||||
./enb -d ../T_messages.txt -p 2022
|
||||
```
|
||||
|
||||
That will launch the GUI tool to analyze the proper running of the
|
||||
softmodem.
|
||||
|
||||
And in another terminal, run:
|
||||
|
||||
```shell
|
||||
cd common/utils/T/tracer
|
||||
./to_vcd -d ../T_messages.txt -p 2022 -vcd -o /tmp/openair_dump_eNB.vcd
|
||||
```
|
||||
|
||||
That will dump the VCD traces generated by the softmodem to the
|
||||
file `/tmp/openair_dump_eNB.vcd`.
|
||||
|
||||
The `multi` tracer waits for other tracers to connect to the port 2022.
|
||||
So you pass `-p 2022` to a tracer so that it connects to the `multi`
|
||||
tracer. This port can be changed with the `-lp` option.
|
||||
|
||||
For example to listen to port 4321, run `multi` as:
|
||||
|
||||
```shell
|
||||
./multi -d ../T_messages.txt -lp 4321
|
||||
```
|
||||
|
||||
Then you would pass `-p 4321` to any tracer for it to connect to `multi`.
|
||||
|
||||
As a reminder, to trace `lte-softmodem`, you run it as:
|
||||
|
||||
```shell
|
||||
sudo ./lte-softmodem -O config_file.conf --T_stdout 0
|
||||
```
|
||||
|
||||
The important part is `--T_stdout 0`.
|
||||
|
||||
The order to launch the various programs (`multi`, the softmodem, other
|
||||
tracers) is not important.
|
||||
@@ -0,0 +1,34 @@
|
||||
# Record
|
||||
|
||||
First, read the [basic usage](./basic.md) to compile things.
|
||||
|
||||
To record, you use the `record` tracer.
|
||||
|
||||
To send a trace to Eurecom, you run (unless we specifically ask you
|
||||
to activate/deactivate specific traces):
|
||||
|
||||
```shell
|
||||
./record -d ../T_messages.txt -o record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG
|
||||
```
|
||||
|
||||
And then you run the program to trace (`lte-softmodem`, `oaisim`, whatever)
|
||||
as explained in [basic usage](./basic.md).
|
||||
|
||||
To stop the recording, you simply press `control+c` to end `record`.
|
||||
|
||||
You send to Eurecom the file `record.raw`. The file `T_messages.txt` is not needed.
|
||||
|
||||
To get a list of options, run:
|
||||
|
||||
```shell
|
||||
./record -h
|
||||
```
|
||||
|
||||
The options `-ON`, `-OFF`, `-on` and `-off` are processed in order.
|
||||
In the example above we first activate all the traces (`-ON`) and then
|
||||
deactivate specific ones (more precisely, in this particular case:
|
||||
the *groups* of traces `VCD`, `HEAVY`, `LEGACY_GROUP_TRACE` and
|
||||
`LEGACY_GROUP_DEBUG`).
|
||||
|
||||
You can then [replay](./replay.md) the recorded file or send it to others so they
|
||||
can analyse things.
|
||||
@@ -0,0 +1,39 @@
|
||||
# Replay
|
||||
|
||||
First, read the [basic usage](./basic.md) to compile things.
|
||||
|
||||
Then, read [record](./record.md) to know how to record a trace.
|
||||
|
||||
To replay, you use the `replay` program. It will act
|
||||
as a *tracee* (`lte-softmodem`, `oaisim`, etc.).
|
||||
|
||||
Then you use your usual tracer, eg. `enb` or `textlog`.
|
||||
|
||||
Since the T is constantly evolving you may need to extract
|
||||
`T_messages.txt` contained in a trace to be able to process
|
||||
the trace.
|
||||
|
||||
## Example
|
||||
|
||||
Download [example.raw](./example.raw). This example contains:
|
||||
* MAC PDUs as sent and received by the eNodeB
|
||||
* RRC info messages the eNodeB produced.
|
||||
|
||||
First step is to extract `T_messages.txt` from this trace.
|
||||
|
||||
```shell
|
||||
./extract_config -i example.raw > extracted_T_messages.txt
|
||||
```
|
||||
|
||||
Then you use `replay` to act as a regular *tracee*:
|
||||
|
||||
```shell
|
||||
./replay -i example.raw
|
||||
```
|
||||
|
||||
And then, while `replay` is still running, you use the tracer
|
||||
you want, for example the `textlog` tracer:
|
||||
|
||||
```shell
|
||||
./textlog -d extracted_T_messages.txt -no-gui -ON -full
|
||||
```
|
||||
@@ -0,0 +1,21 @@
|
||||
# to_vcd
|
||||
|
||||
This tracer is used to dump a VCD trace of the softmodem.
|
||||
|
||||
The basic usage is:
|
||||
|
||||
```shell
|
||||
cd common/utils/T/tracer
|
||||
./to_vcd -d ../T_messages.txt -vcd -o /tmp/openair_dump_eNB.vcd
|
||||
```
|
||||
|
||||
Apart from VCD specific traces, you can dump to VCD other T traces.
|
||||
Use `-b` and `-l` options. For example, to only log DLSCH scheduler VCD traces, use:
|
||||
```shell
|
||||
./to_vcd -d ../T_messages.txt -o /tmp/openair_dump_eNB.vcd -b VCD_FUNCTION_SCHEDULE_DLSCH value mac_schedule_dlsch
|
||||
```
|
||||
|
||||
For more help, run:
|
||||
```shell
|
||||
./to_vcd -h
|
||||
```
|
||||
@@ -0,0 +1,158 @@
|
||||
# MAC PDUs and wireshark
|
||||
|
||||
First, read the [basic usage](./basic.md) to compile things.
|
||||
|
||||
It is possible to use `wireshark` to analyse MAC PDUs for UEs,
|
||||
MIBs, SIBs, and random accesses seen by the eNodeB.
|
||||
|
||||
## Live usage
|
||||
|
||||
Launch wireshark and listen on the local interface (lo).
|
||||
Set the filter to `udp.port==9999` and read below
|
||||
for configuration.
|
||||
|
||||
Run the softmodem with the correct command line arguments
|
||||
(see [basic usage](./basic.md)).
|
||||
|
||||
Then run:
|
||||
|
||||
```shell
|
||||
./macpdu2wireshark -d ../T_messages.txt -live
|
||||
```
|
||||
|
||||
For other options of `macpdu2wireshark`, run:
|
||||
|
||||
```shell
|
||||
./macpdu2wireshark -h
|
||||
```
|
||||
|
||||
You can for example disable MIB and SIB logging, or log only
|
||||
a given number of them.
|
||||
|
||||
## Record and replay
|
||||
|
||||
You need to record some specific traces. As of 2018-10-30
|
||||
you have to use the group:
|
||||
* `WIRESHARK`
|
||||
|
||||
That is, run:
|
||||
|
||||
```shell
|
||||
./record -d ../T_messages.txt -o /tmp/record.raw -on WIRESHARK
|
||||
```
|
||||
|
||||
With a recorded trace you then use `macpdu2wireshark`.
|
||||
|
||||
## Example
|
||||
|
||||
Download [example.raw](example.raw). This example contains
|
||||
MIBs, SIBs and a connection made by an UE followed by its
|
||||
disconnection.
|
||||
|
||||
First step is to extract `T_messages.txt` from this trace.
|
||||
|
||||
```shell
|
||||
./extract_config -i example.raw > extracted_T_messages.txt
|
||||
```
|
||||
|
||||
Then you run `wireshark`, capture on `lo` and set the
|
||||
filter to `udp.dstport==9999`.
|
||||
|
||||
While `wireshark` is running, you do:
|
||||
|
||||
```shell
|
||||
./macpdu2wireshark -d extracted_T_messages.txt -i example.raw -no-mib -no-sib
|
||||
```
|
||||
|
||||
In `wireshark` you should see something similar to the following:
|
||||
|
||||

|
||||
|
||||
## Configure wireshark for LTE
|
||||
|
||||
To dissect the packets, you need to configure `wireshark`.
|
||||
|
||||
In the menu, choose `Edit->Preferences`.
|
||||
|
||||
In the preference window, unroll `Protocols`.
|
||||
|
||||
Go to `UDP` and activate `Try heuristic sub-dissectors first`.
|
||||
|
||||
Depending on your version of `wireshark`, you may need to go to `MAC-LTE`
|
||||
and activate `Try Heuristic LTE-MAC over UDP framing` if this option
|
||||
is present.
|
||||
|
||||
For newer versions (after 2.0 as says wireshark's documentation),
|
||||
heuristic activation is moved to the `Enabled Protocols` window
|
||||
(in the menu `Analyze`). In the `enabled protocols` window, search
|
||||
for `lte` and select `mac_lte_udp` to have `MAC-LTE over UDP`.
|
||||
|
||||
You may also want to configure other parameters in `MAC-LTE`,
|
||||
`RLC-LTE`, `PDCP-LTE`, and maybe others. Check the documentation
|
||||
of `wireshark`.
|
||||
|
||||
It is advised to use a recent version of wireshark (say more than 2.4).
|
||||
|
||||
## Configure wireshark for NR
|
||||
|
||||
Use a recent version of wireshark. The steps below were done using
|
||||
version 3.3.2. Maybe some options are different for your version
|
||||
of wireshark. Adapt as necessary.
|
||||
|
||||
First, do the previous steps for LTE.
|
||||
|
||||
Then, in the menu, choose `Edit->Preferences`.
|
||||
|
||||
In the preference window, unroll `Protocols`.
|
||||
|
||||
Go to `MAC-NR`. Select both options (`Attempt to decode BCCH, PCCH and CCCH data using NR RRC dissector`
|
||||
and `Attempt to dissect LCID 1-3 as srb1-3`).
|
||||
|
||||
For `Source of LCID -> drb channel settings` choose option `From static table`.
|
||||
Then click the `Edit...` button of `LCID -> DRB Mappings Table`.
|
||||
|
||||
In the new window, click on `+`. Choose LCID `4`, DRBID `1`, UL RLC Bearer
|
||||
Type `AM, SN Len=18`, same thing for DL RLC Bearer Type.
|
||||
|
||||
Then click OK.
|
||||
|
||||
Now, go to `RLC-NR`. Select `Call PDCP dissector for SRB PDUs`.
|
||||
|
||||
For `Call PDCP dissector for UL DRB PDUs` choose `18-bit SN`. Same
|
||||
for DL.
|
||||
|
||||
Select `Call RRC dissector for CCCH PDUs`.
|
||||
|
||||
You don't need to select `May see RLC headers only` and
|
||||
`Try to reassemble UM frames`.
|
||||
|
||||
Now, go to `PDCP-NR`. Select what you want in there. It's good
|
||||
to select `Show uncompressed User-Plane data as IP`. Also good
|
||||
to select `Show unciphered Signalling-Plane data as RRC`.
|
||||
For `Do sequence number analysis` it can be good to use
|
||||
`Only-RLC-frames` but anything will do. We don't use ROHC so you
|
||||
don't need to select `Attempt to decode ROHC data`. And the
|
||||
layer info to show depends on what you want to analyse.
|
||||
`Traffic Info` is a good choice.
|
||||
|
||||
You are done with the preferences. You can click OK.
|
||||
|
||||
Then, in the menu `Analyze`, choose `Enabled Protocols...`. In the new window
|
||||
search for `nr` and select `mac_nr_udp` to have `MAC-NR over UDP`.
|
||||
|
||||
And that's it. Maybe other settings can be changed, but those steps should be
|
||||
enough for a start.
|
||||
|
||||
Note: not all versions of Wireshark correctly dissect encapsulated packets. For instance, we observed that Wireshark v3.4.8 did not call the PDCP dissector for a PDCP PDU split in two RLC SDUs. On the other hand, Wireshark v3.7.0 showed it just fine.
|
||||
|
||||
## Alternative to wireshark
|
||||
|
||||
While using `macpdu2wireshark` with the `-live` option, it is possible to use `tcpdump` instead of `wireshak` to record MAC PDUs and also other types of traffic (sctp, gtp) in the same output pcap file.
|
||||
|
||||
A "catch all" solution is to run:
|
||||
|
||||
```
|
||||
sudo tcpdump -n -iany "udp port 9999 or udp port 2152 or sctp or port 38462 or port 38472 or port 38412 or port 2153" -w /tmp/rec.pcap
|
||||
```
|
||||
|
||||
(This is an example, other solutions are also possible.)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 262 KiB |
@@ -20,7 +20,7 @@ T_IDs.h: $(GENIDS) T_messages.txt
|
||||
|
||||
check_vcd: T_IDs.h T_messages.txt.h
|
||||
gcc -Wall -I. -I.. -I../itti -I../../../openair2/COMMON -Itracer -o _check_vcd check_vcd.c tracer/database.c tracer/utils.c -lm -pthread
|
||||
./_check_vcd || (rm -f ./_check_vcd ./T_IDs.h ./T_messages.txt.h && false)
|
||||
./_check_vcd T_messages.txt ../LOG/vcd_signal_dumper.h || (rm -f ./_check_vcd ./T_IDs.h ./T_messages.txt.h && false)
|
||||
rm -f ./_check_vcd
|
||||
|
||||
.PHONY: check_vcd
|
||||
|
||||
@@ -67,14 +67,17 @@ void err(char *fmt, ...)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* to disable the checks done by this program, uncomment the following
|
||||
* line, ie. remove the leading '//'
|
||||
*/
|
||||
//return 0;
|
||||
|
||||
void *database = parse_database("T_messages.txt");
|
||||
if (argc != 3) err("usage: %s <T_messages.txt> <vcd_signal_dumper.h>", argv[0]);
|
||||
char *T_msg_txt = argv[1];
|
||||
char *vcd_sig_dmp = argv[2];
|
||||
void *database = parse_database(T_msg_txt);
|
||||
int number_of_events;
|
||||
int first_var = -1;
|
||||
int last_var;
|
||||
@@ -212,8 +215,8 @@ int main(void)
|
||||
* VCD_VARIABLE_ABC or VCD_FUNCTION_XYZ
|
||||
*/
|
||||
i = first_var;
|
||||
in = fopen("../LOG/vcd_signal_dumper.h", "r");
|
||||
if (in == NULL) err("could not open ../LOG/vcd_signal_dumper.h");
|
||||
in = fopen(vcd_sig_dmp, "r");
|
||||
if (in == NULL) err("could not open %s\n", vcd_sig_dmp);
|
||||
while (1) {
|
||||
char *x = " VCD_SIGNAL_DUMPER_VARIABLES_";
|
||||
ssize_t r;
|
||||
@@ -253,7 +256,9 @@ int main(void)
|
||||
err("%s is not correct in T_messages.txt", name);
|
||||
i++;
|
||||
}
|
||||
free(l);
|
||||
fclose(in);
|
||||
free_database(database);
|
||||
if (i != last_fun + 1) err("VCD FUNCTIONS wrong in T_messages.txt");
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
add_library(tracer_utils OBJECT config.c database.c event.c handler.c utils.c)
|
||||
target_link_libraries(tracer_utils PUBLIC m pthread)
|
||||
|
||||
add_library(tracer_events OBJECT event_selector.c)
|
||||
|
||||
add_executable(record record.c)
|
||||
target_link_libraries(record PRIVATE tracer_utils)
|
||||
|
||||
add_executable(replay replay.c)
|
||||
target_link_libraries(replay PRIVATE tracer_utils)
|
||||
|
||||
add_executable(extract_config extract_config.c)
|
||||
target_link_libraries(extract_config PRIVATE tracer_utils)
|
||||
|
||||
add_executable(extract_input_subframe extract_input_subframe.c)
|
||||
target_link_libraries(extract_input_subframe PRIVATE tracer_utils)
|
||||
|
||||
add_executable(extract_output_subframe extract_output_subframe.c)
|
||||
target_link_libraries(extract_output_subframe PRIVATE tracer_utils)
|
||||
|
||||
add_executable(extract extract.c)
|
||||
target_link_libraries(extract PRIVATE tracer_utils)
|
||||
|
||||
add_executable(textlog textlog.c)
|
||||
target_link_libraries(textlog PRIVATE tracer_utils tracer_filter tracer_gui
|
||||
tracer_logger tracer_view tracer_events)
|
||||
|
||||
|
||||
find_library(png png REQUIRED)
|
||||
add_executable(enb enb.c)
|
||||
target_link_libraries(enb PRIVATE tracer_utils tracer_filter tracer_gui
|
||||
tracer_logger tracer_view tracer_events)
|
||||
target_link_libraries(enb PRIVATE png)
|
||||
|
||||
add_executable(ue ue.c)
|
||||
target_link_libraries(ue PRIVATE tracer_utils tracer_filter tracer_gui
|
||||
tracer_logger tracer_view tracer_events)
|
||||
target_link_libraries(ue PRIVATE png)
|
||||
|
||||
add_executable(vcd vcd.c)
|
||||
target_link_libraries(vcd PRIVATE tracer_utils tracer_filter tracer_gui
|
||||
tracer_logger tracer_view tracer_events)
|
||||
|
||||
add_executable(to_vcd to_vcd.c)
|
||||
target_link_libraries(to_vcd PRIVATE tracer_utils tracer_filter tracer_gui
|
||||
tracer_logger tracer_view tracer_events)
|
||||
|
||||
add_executable(macpdu2wireshark macpdu2wireshark.c)
|
||||
target_link_libraries(macpdu2wireshark PRIVATE tracer_utils)
|
||||
|
||||
add_executable(multi multi.c)
|
||||
target_link_libraries(multi PRIVATE tracer_utils T)
|
||||
target_include_directories(multi PRIVATE ..)
|
||||
|
||||
add_executable(gnb gnb.c)
|
||||
target_link_libraries(gnb PRIVATE tracer_utils tracer_filter tracer_gui
|
||||
tracer_logger tracer_view tracer_events)
|
||||
target_link_libraries(gnb PRIVATE png)
|
||||
|
||||
add_subdirectory(filter)
|
||||
add_subdirectory(gui)
|
||||
add_subdirectory(logger)
|
||||
add_subdirectory(view)
|
||||
|
||||
add_custom_target(T_tools)
|
||||
add_dependencies(T_tools
|
||||
record replay extract_config textlog enb ue vcd macpdu2wireshark
|
||||
extract_input_subframe extract_output_subframe to_vcd extract multi
|
||||
gnb)
|
||||
add_dependencies(nr-softmodem T_tools)
|
||||
add_dependencies(nr-uesoftmodem T_tools)
|
||||
add_dependencies(lte-softmodem T_tools)
|
||||
add_dependencies(lte-uesoftmodem T_tools)
|
||||
@@ -43,6 +43,14 @@ typedef struct {
|
||||
buffer value;
|
||||
} parser;
|
||||
|
||||
void *my_bsearch(const void *key, const void *base,
|
||||
size_t nmemb, size_t size,
|
||||
int (*compar)(const void *, const void *))
|
||||
{
|
||||
if (nmemb == 0) return NULL;
|
||||
return bsearch(key, base, nmemb, size, compar);
|
||||
}
|
||||
|
||||
void put(buffer *b, int c)
|
||||
{
|
||||
if (b->size == b->maxsize) {
|
||||
@@ -125,7 +133,7 @@ int string_cmp(const void *_p1, const void *_p2)
|
||||
|
||||
id *add_id(database *r, char *idname, int i)
|
||||
{
|
||||
if (bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp) != NULL)
|
||||
if (my_bsearch(&(id){.name=idname}, r->i, r->isize, sizeof(id), id_cmp) != NULL)
|
||||
{ printf("ERROR: ID '%s' declared more than once\n", idname); exit(1); }
|
||||
if ((r->isize & 1023) == 0) {
|
||||
r->i = realloc(r->i, (r->isize + 1024) * sizeof(id));
|
||||
@@ -143,14 +151,14 @@ id *add_id(database *r, char *idname, int i)
|
||||
r->i[r->isize].id = i;
|
||||
r->isize++;
|
||||
qsort(r->i, r->isize, sizeof(id), id_cmp);
|
||||
return (id*)bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp);
|
||||
return (id*)my_bsearch(&(id){.name=idname}, r->i, r->isize, sizeof(id), id_cmp);
|
||||
}
|
||||
|
||||
group *get_group(database *r, char *group_name)
|
||||
{
|
||||
group *ret;
|
||||
|
||||
ret = bsearch(&(group){name:group_name},
|
||||
ret = my_bsearch(&(group){.name=group_name},
|
||||
r->g, r->gsize, sizeof(group), group_cmp);
|
||||
if (ret != NULL) return ret;
|
||||
|
||||
@@ -166,7 +174,7 @@ group *get_group(database *r, char *group_name)
|
||||
|
||||
qsort(r->g, r->gsize, sizeof(group), group_cmp);
|
||||
|
||||
return bsearch(&(group){name:group_name},
|
||||
return my_bsearch(&(group){.name=group_name},
|
||||
r->g, r->gsize, sizeof(group), group_cmp);
|
||||
}
|
||||
|
||||
@@ -182,7 +190,7 @@ void group_add_id(group *g, char *id)
|
||||
|
||||
void id_add_group(id *i, char *group)
|
||||
{
|
||||
char *g = bsearch(&group, i->groups, i->gsize, sizeof(char *), string_cmp);
|
||||
char *g = my_bsearch(&group, i->groups, i->gsize, sizeof(char *), string_cmp);
|
||||
if (g != NULL) return;
|
||||
|
||||
if ((i->gsize & 1023) == 0) {
|
||||
@@ -392,7 +400,7 @@ void list_groups(void *_d)
|
||||
static int onoff_id(database *d, char *name, int *a, int onoff)
|
||||
{
|
||||
id *i;
|
||||
i = bsearch(&(id){name:name}, d->i, d->isize, sizeof(id), id_cmp);
|
||||
i = my_bsearch(&(id){.name=name}, d->i, d->isize, sizeof(id), id_cmp);
|
||||
if (i == NULL) return 0;
|
||||
a[i->id] = onoff;
|
||||
printf("turning %s %s\n", onoff ? "ON" : "OFF", name);
|
||||
@@ -403,7 +411,7 @@ static int onoff_group(database *d, char *name, int *a, int onoff)
|
||||
{
|
||||
group *g;
|
||||
int i;
|
||||
g = bsearch(&(group){name:name}, d->g, d->gsize, sizeof(group), group_cmp);
|
||||
g = my_bsearch(&(group){.name=name}, d->g, d->gsize, sizeof(group), group_cmp);
|
||||
if (g == NULL) return 0;
|
||||
for (i = 0; i < g->size; i++) onoff_id(d, g->ids[i], a, onoff);
|
||||
return 1;
|
||||
@@ -442,7 +450,7 @@ char *event_vcd_name_from_id(void *_database, int id)
|
||||
int event_id_from_name(void *_database, char *name)
|
||||
{
|
||||
database *d = _database;
|
||||
id *i = (id*)bsearch(&(id){name:name}, d->i, d->isize, sizeof(id), id_cmp);
|
||||
id *i = (id*)my_bsearch(&(id){.name=name}, d->i, d->isize, sizeof(id), id_cmp);
|
||||
if (i == NULL)
|
||||
{ printf("%s:%d: '%s' not found\n", __FILE__, __LINE__, name); abort(); }
|
||||
return i->id;
|
||||
@@ -516,3 +524,31 @@ void database_get_generic_description(void *_d, int id,
|
||||
PUTC(&o, 0);
|
||||
*desc = o.obuf;
|
||||
}
|
||||
|
||||
void free_database(void *_d)
|
||||
{
|
||||
database *d = _d;
|
||||
int i;
|
||||
int j;
|
||||
free(d->name);
|
||||
for (i = 0; i < d->isize; i++) {
|
||||
free(d->i[i].name);
|
||||
free(d->i[i].desc);
|
||||
free(d->i[i].groups);
|
||||
for (j = 0; j < d->i[i].asize; j++) {
|
||||
free(d->i[i].arg_type[j]);
|
||||
free(d->i[i].arg_name[j]);
|
||||
}
|
||||
free(d->i[i].arg_type);
|
||||
free(d->i[i].arg_name);
|
||||
free(d->i[i].vcd_name);
|
||||
}
|
||||
free(d->i);
|
||||
for (i = 0; i < d->gsize; i++) {
|
||||
free(d->g[i].name);
|
||||
free(d->g[i].ids);
|
||||
}
|
||||
free(d->g);
|
||||
free(d->id_to_pos);
|
||||
free(d);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
/* returns an opaque pointer - truly a 'database *', see database.c */
|
||||
void *parse_database(char *filename);
|
||||
void free_database(void *database);
|
||||
void dump_database(void *database);
|
||||
void list_ids(void *database);
|
||||
void list_groups(void *database);
|
||||
|
||||
@@ -55,8 +55,8 @@ int main(int n, char **v)
|
||||
int found;
|
||||
int count = 1;
|
||||
int check_time = 0;
|
||||
time_t sec;
|
||||
long nsec;
|
||||
time_t sec = 0; /* initialization not necessary but gcc is not happy */
|
||||
long nsec = 0; /* initialization not necessary but gcc is not happy */
|
||||
|
||||
for (i = 1; i < n; i++) {
|
||||
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
add_library(tracer_filter STATIC filter.c)
|
||||
target_include_directories(tracer_filter PRIVATE ..)
|
||||
@@ -0,0 +1,10 @@
|
||||
include(FindPkgConfig)
|
||||
pkg_check_modules(xft REQUIRED xft)
|
||||
find_library(X11 X11 REQUIRED)
|
||||
add_library(tracer_gui STATIC
|
||||
init.c loop.c toplevel_window.c x.c container.c widget.c
|
||||
gui.c label.c textarea.c event.c xy_plot.c textlist.c notify.c
|
||||
positioner.c timeline.c space.c image.c)
|
||||
|
||||
target_link_libraries(tracer_gui PRIVATE pthread m ${xft_LIBRARIES} X11)
|
||||
target_include_directories(tracer_gui PRIVATE ${xft_INCLUDE_DIRS})
|
||||
@@ -107,7 +107,7 @@ void send_event(gui *_gui, enum event_type type, ...)
|
||||
struct gui *g = _gui;
|
||||
int do_write = 0;
|
||||
va_list ap;
|
||||
struct event *e;
|
||||
struct event *e = NULL; /* initialization not necessary but gcc is not happy */
|
||||
|
||||
if (g->queued_events == NULL) do_write = 1;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define _X_DEFS_H_
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <Xft.h>
|
||||
#include <X11/Xft/Xft.h>
|
||||
|
||||
struct x_connection {
|
||||
Display *d;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
add_library(tracer_logger STATIC
|
||||
logger.c textlog.c framelog.c ttilog.c timelog.c ticklog.c iqlog.c
|
||||
iqdotlog.c ticked_ttilog.c throughputlog.c)
|
||||
target_link_libraries(tracer_logger PRIVATE pthread tracer_filter)
|
||||
target_include_directories(tracer_logger PRIVATE ..)
|
||||
@@ -86,7 +86,7 @@ int main(int n, char **v)
|
||||
int i;
|
||||
event_handler *h;
|
||||
logger *textlog;
|
||||
gui *g;
|
||||
gui *g = NULL; /* initialization not necessary but gcc is not happy */
|
||||
int gui_mode = 0;
|
||||
view *out;
|
||||
int gui_active = 1;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
add_library(tracer_view STATIC
|
||||
stdout.c textlist.c xy.c tti.c time.c ticktime.c scrolltti.c)
|
||||
target_link_libraries(tracer_view PRIVATE pthread)
|
||||
target_include_directories(tracer_view PRIVATE ../logger)
|
||||
target_include_directories(tracer_view PUBLIC ..)
|
||||
@@ -140,7 +140,7 @@ extern "C" {
|
||||
t->message_queue.insert(t->message_queue.begin(), message);
|
||||
eventfd_t sem_counter = 1;
|
||||
AssertFatal ( sizeof(sem_counter) == write(t->sem_fd, &sem_counter, sizeof(sem_counter)), "");
|
||||
LOG_D(ITTI,"sent messages id=%d to %s\n",message_id, t->admin.name);
|
||||
LOG_D(ITTI, "sent messages id=%s messages_info to %s\n", messages_info[message_id].name, t->admin.name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -339,9 +339,6 @@ int history_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
|
||||
memset(cmds,0,sizeof(cmds));
|
||||
sscanf(buff,"%9s %9s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] );
|
||||
|
||||
if (cmds[0] == NULL)
|
||||
return CMDSTATUS_VARNOTFOUND;
|
||||
|
||||
if (strncasecmp(cmds[0],"list",4) == 0) {
|
||||
HIST_ENTRY **hist = history_list();
|
||||
|
||||
|
||||
+2
-2
@@ -271,7 +271,7 @@ The following features are valid for the gNB and the 5G-NR UE.
|
||||
- Support for 256 QAM
|
||||
* NR-PUCCH
|
||||
- Format 0 (2 bits, for ACK/NACK and SR)
|
||||
- Format 2 (up to 11 bits, mainly for CSI feedback)
|
||||
- Format 2 (mainly for CSI feedback)
|
||||
* NR-SRS
|
||||
- SRS signal reception
|
||||
- Channel estimation (with T tracer real time monitoring)
|
||||
@@ -443,7 +443,7 @@ The following features are valid for the gNB and the 5G-NR UE.
|
||||
- Support for up to 2 layers
|
||||
* NR-PUCCH
|
||||
- Format 0 (2 bits for ACK/NACK and SR)
|
||||
- Format 2 (up to 11 bits, mainly for CSI feedback)
|
||||
- Format 2 (mainly for CSI feedback)
|
||||
- Format 1 (limited testing)
|
||||
- Format 3 and 4 present but old code never tested (need restructuring before verification)
|
||||
* NR-SRS
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@ Legacy unmaintained files:
|
||||
|
||||
## General
|
||||
|
||||
- The [T tracer](https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/T/): a generic tracing tool (VCD, Wireshark, GUI, to save for later, ...)
|
||||
- The [T tracer](../common/utils/T/DOC/T.md): a generic tracing tool (VCD, Wireshark, GUI, to save for later, ...)
|
||||
- [OPT](../openair2/UTIL/OPT/README.txt): how to trace to wireshark
|
||||
- The [configuration module](../common/config/DOC/config.md)
|
||||
- The [logging module](../common/utils/LOG/DOC/log.md)
|
||||
|
||||
@@ -40,4 +40,4 @@ RUN /bin/sh oaienv && \
|
||||
mkdir -p log && \
|
||||
export CC=/usr/bin/clang && \
|
||||
export CXX=/usr/bin/clang++ && \
|
||||
./build_oai --phy_simulators --gNB --eNB --nrUE --UE --ninja --verbose-ci --noavx512 -c --cmake-opt -DCMAKE_C_FLAGS=-Werror --cmake-opt -DCMAKE_CXX_FLAGS=-Werror
|
||||
./build_oai --phy_simulators --gNB --eNB --nrUE --UE --ninja --verbose-ci --noavx512 --disable-T-Tracer -c --cmake-opt -DCMAKE_C_FLAGS=-Werror --cmake-opt -DCMAKE_CXX_FLAGS=-Werror
|
||||
|
||||
+1
-1
@@ -776,7 +776,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
|
||||
} else if (nextslot_type == NR_UPLINK_SLOT) {
|
||||
flags_burst = TX_BURST_END;
|
||||
} else {
|
||||
flags_burst = TX_BURST_MIDDLE;
|
||||
flags_burst = proc->first_tx == 1 ? TX_BURST_START : TX_BURST_MIDDLE;
|
||||
}
|
||||
}
|
||||
} else { // FDD
|
||||
|
||||
+2
-27
@@ -505,8 +505,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD) {
|
||||
|
||||
void *txp[NB_ANTENNAS_TX];
|
||||
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
|
||||
txp[i] = (void *)&UE->common_vars.txdata[i][UE->frame_parms.get_samples_slot_timestamp(
|
||||
proc->nr_slot_tx, &UE->frame_parms, 0)];
|
||||
txp[i] = (void *)&UE->common_vars.txData[i][UE->frame_parms.get_samples_slot_timestamp(proc->nr_slot_tx, &UE->frame_parms, 0)];
|
||||
|
||||
radio_tx_burst_flag_t flags = TX_BURST_INVALID;
|
||||
|
||||
@@ -868,7 +867,6 @@ void *UE_thread(void *arg) {
|
||||
nr_rxtx_thread_data_t curMsg = {0};
|
||||
curMsg.UE=UE;
|
||||
// update thread index for received subframe
|
||||
curMsg.proc.CC_id = UE->CC_id;
|
||||
curMsg.proc.nr_slot_rx = slot_nr;
|
||||
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;
|
||||
@@ -876,16 +874,6 @@ void *UE_thread(void *arg) {
|
||||
curMsg.proc.rx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.frame_rx, curMsg.proc.nr_slot_rx);
|
||||
curMsg.proc.tx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.frame_tx, curMsg.proc.nr_slot_tx);
|
||||
curMsg.proc.decoded_frame_rx=-1;
|
||||
//LOG_I(PHY,"Process slot %d total gain %d\n", slot_nr, UE->rx_total_gain_dB);
|
||||
|
||||
#ifdef OAI_ADRV9371_ZC706
|
||||
/*uint32_t total_gain_dB_prev = 0;
|
||||
if (total_gain_dB_prev != UE->rx_total_gain_dB) {
|
||||
total_gain_dB_prev = UE->rx_total_gain_dB;
|
||||
openair0_cfg[0].rx_gain[0] = UE->rx_total_gain_dB;
|
||||
UE->rfdevice.trx_set_gains_func(&UE->rfdevice,&openair0_cfg[0]);
|
||||
}*/
|
||||
#endif
|
||||
|
||||
int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms);
|
||||
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
|
||||
@@ -938,7 +926,7 @@ void *UE_thread(void *arg) {
|
||||
timing_advance = UE->timing_advance;
|
||||
}
|
||||
|
||||
nr_ue_rrc_timer_trigger(UE->Mod_id, curMsg.proc.frame_tx, curMsg.proc.nr_slot_tx);
|
||||
nr_ue_rrc_timer_trigger(UE->Mod_id, curMsg.proc.frame_tx, curMsg.proc.nr_slot_tx, curMsg.proc.gNB_id);
|
||||
|
||||
// Start TX slot processing here. It runs in parallel with RX slot processing
|
||||
notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_tx, &txFifo, processSlotTX);
|
||||
@@ -1010,16 +998,3 @@ void init_NR_UE_threads(int nb_inst) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* HACK: this function is needed to compile the UE
|
||||
* fix it somehow
|
||||
*/
|
||||
int find_dlsch(uint16_t rnti,
|
||||
PHY_VARS_eNB *eNB,
|
||||
find_type_t type)
|
||||
{
|
||||
printf("you cannot read this\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
void multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP) {}
|
||||
|
||||
@@ -442,6 +442,9 @@ typedef struct {
|
||||
uint16_t start_rb;
|
||||
uint16_t number_symbols;
|
||||
uint16_t start_symbol;
|
||||
// TODO this is a workaround to make it work
|
||||
// implementation is also a bunch of workarounds
|
||||
uint16_t rb_offset;
|
||||
uint16_t dlDmrsSymbPos;
|
||||
uint8_t dmrsConfigType;
|
||||
uint8_t prb_bundling_size_ind;
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||
#include "assertions.h"
|
||||
|
||||
//#define POLAR_CODING_DEBUG
|
||||
|
||||
static inline void updateCrcChecksum2(int xlen,
|
||||
int ylen,
|
||||
uint8_t crcChecksum[xlen][ylen],
|
||||
@@ -611,24 +613,78 @@ uint32_t polar_decoder_int16(int16_t *input,
|
||||
uint8_t aggregation_level )
|
||||
{
|
||||
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, true);
|
||||
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
printf("\nRX\n");
|
||||
printf("rm:");
|
||||
for (int i = 0; i < polarParams->N; i++) {
|
||||
if (i % 4 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
printf("%i", input[i] < 0 ? 1 : 0);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N);
|
||||
nr_polar_rate_matching_int16(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength);
|
||||
nr_polar_rate_matching_int16(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength, polarParams->i_bil);
|
||||
|
||||
for (int i=0; i<polarParams->N; i++) {
|
||||
if (d_tilde[i]<-128) d_tilde[i]=-128;
|
||||
else if (d_tilde[i]>127) d_tilde[i]=128;
|
||||
}
|
||||
|
||||
memcpy((void *)&polarParams->tree.root->alpha[0],(void *)&d_tilde[0],sizeof(int16_t)*polarParams->N);
|
||||
generic_polar_decoder(polarParams,polarParams->tree.root);
|
||||
//Extract the information bits (û to ĉ)
|
||||
uint64_t Cprime[4]= {0,0,0,0};
|
||||
uint64_t B[4]= {0,0,0,0};
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
printf("d: ");
|
||||
for (int i = 0; i < polarParams->N; i++) {
|
||||
if (i % 4 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
printf("%i", d_tilde[i] < 0 ? 1 : 0);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
for (int i=0; i<polarParams->K; i++) Cprime[i>>6] = Cprime[i>>6] | ((uint64_t)polarParams->nr_polar_U[polarParams->Q_I_N[i]])<<(i&63);
|
||||
memcpy((void *)&polarParams->tree.root->alpha[0], (void *)&d_tilde[0], sizeof(int16_t) * polarParams->N);
|
||||
memset(polarParams->nr_polar_U, 0, polarParams->N * sizeof(uint8_t));
|
||||
generic_polar_decoder(polarParams, polarParams->tree.root);
|
||||
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
printf("u: ");
|
||||
for (int i = 0; i < polarParams->N; i++) {
|
||||
if (i % 4 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
printf("%i", polarParams->nr_polar_U[i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
// Extract the information bits (û to ĉ)
|
||||
uint64_t Cprime[4]= {0};
|
||||
nr_polar_info_extraction_from_u(Cprime,
|
||||
polarParams->nr_polar_U,
|
||||
polarParams->information_bit_pattern,
|
||||
polarParams->parity_check_bit_pattern,
|
||||
polarParams->N,
|
||||
polarParams->n_pc);
|
||||
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
printf("c: ");
|
||||
for (int n = 0; n < polarParams->K; n++) {
|
||||
if (n % 4 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
int n1 = n >> 6;
|
||||
int n2 = n - (n1 << 6);
|
||||
printf("%lu", (Cprime[n1] >> n2) & 1);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
//Deinterleaving (ĉ to b)
|
||||
uint8_t *Cprimebyte = (uint8_t *)Cprime;
|
||||
uint64_t B[4] = {0};
|
||||
|
||||
if (polarParams->K<65) {
|
||||
B[0] = polarParams->B_tab0[0][Cprimebyte[0]] |
|
||||
@@ -650,6 +706,21 @@ uint32_t polar_decoder_int16(int16_t *input,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
int B_array = (polarParams->K + 63) >> 6;
|
||||
int n_start = (B_array << 6) - polarParams->K;
|
||||
printf("b: ");
|
||||
for (int n = 0; n < polarParams->K; n++) {
|
||||
if (n % 4 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
int n1 = (n + n_start) >> 6;
|
||||
int n2 = (n + n_start) - (n1 << 6);
|
||||
printf("%lu", (B[B_array - 1 - n1] >> (63 - n2)) & 1);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
int len=polarParams->payloadBits;
|
||||
//int len_mod64=len&63;
|
||||
int crclen = polarParams->crcParityBits;
|
||||
@@ -700,6 +771,21 @@ uint32_t polar_decoder_int16(int16_t *input,
|
||||
else if (crclen==6) crc = (uint64_t)(crc6(A64_flip,8*offset+len)>>26)&0x3f;
|
||||
}
|
||||
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
int A_array = (len + 63) >> 6;
|
||||
printf("a: ");
|
||||
for (int n = 0; n < len; n++) {
|
||||
if (n % 4 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
int n1 = n >> 6;
|
||||
int n2 = n - (n1 << 6);
|
||||
int alen = n1 == 0 ? len - (A_array << 6) : 64;
|
||||
printf("%lu", (Ar >> (alen - 1 - n2)) & 1);
|
||||
}
|
||||
printf("\n\n");
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
printf("A %llx B %llx|%llx Cprime %llx|%llx (crc %x,rxcrc %llx %d)\n",
|
||||
Ar,
|
||||
|
||||
@@ -106,6 +106,7 @@ struct nrPolar_params {
|
||||
int16_t *Q_F_N;
|
||||
int16_t *Q_PC_N;
|
||||
uint8_t *information_bit_pattern;
|
||||
uint8_t *parity_check_bit_pattern;
|
||||
uint16_t *channel_interleaver_pattern;
|
||||
//uint32_t crc_polynomial;
|
||||
|
||||
@@ -238,24 +239,28 @@ void nr_polar_rate_matching(double *input,
|
||||
|
||||
void nr_polar_rate_matching_int16(int16_t *input,
|
||||
int16_t *output,
|
||||
uint16_t *rmp,
|
||||
uint16_t K,
|
||||
uint16_t N,
|
||||
uint16_t E);
|
||||
const uint16_t *rmp,
|
||||
const uint16_t K,
|
||||
const uint16_t N,
|
||||
const uint16_t E,
|
||||
const uint8_t i_bil);
|
||||
|
||||
void nr_polar_interleaving_pattern(uint16_t K,
|
||||
uint8_t I_IL,
|
||||
uint16_t *PI_k_);
|
||||
|
||||
void nr_polar_info_bit_pattern(uint8_t *ibp,
|
||||
uint8_t *pcbp,
|
||||
int16_t *Q_I_N,
|
||||
int16_t *Q_F_N,
|
||||
uint16_t *J,
|
||||
int16_t *Q_PC_N,
|
||||
const uint16_t *J,
|
||||
const uint16_t *Q_0_Nminus1,
|
||||
uint16_t K,
|
||||
uint16_t N,
|
||||
uint16_t E,
|
||||
uint8_t n_PC);
|
||||
uint8_t n_PC,
|
||||
uint8_t n_pc_wm);
|
||||
|
||||
void nr_polar_info_bit_extraction(uint8_t *input,
|
||||
uint8_t *output,
|
||||
@@ -272,6 +277,22 @@ void nr_byte2bit_uint8_32(uint8_t *in,
|
||||
|
||||
const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits);
|
||||
|
||||
void nr_polar_generate_u(uint64_t *u,
|
||||
const uint64_t *Cprime,
|
||||
const uint8_t *information_bit_pattern,
|
||||
const uint8_t *parity_check_bit_pattern,
|
||||
uint16_t N,
|
||||
uint8_t n_pc);
|
||||
|
||||
void nr_polar_uxG(uint64_t *D, const uint64_t *u, const uint64_t **G_N_tab, uint16_t N);
|
||||
|
||||
void nr_polar_info_extraction_from_u(uint64_t *Cprime,
|
||||
const uint8_t *u,
|
||||
const uint8_t *information_bit_pattern,
|
||||
const uint8_t *parity_check_bit_pattern,
|
||||
uint16_t N,
|
||||
uint8_t n_pc);
|
||||
|
||||
void nr_polar_bit_insertion(uint8_t *input,
|
||||
uint8_t *output,
|
||||
uint16_t N,
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
//#define DEBUG_POLAR_ENCODER
|
||||
//#define DEBUG_POLAR_ENCODER_DCI
|
||||
//#define DEBUG_POLAR_MATLAB
|
||||
//#define POLAR_CODING_DEBUG
|
||||
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||
#include "assertions.h"
|
||||
@@ -262,6 +263,44 @@ void polar_encoder_dci(uint32_t *in,
|
||||
polarReturn;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interleaving of coded bits implementation
|
||||
* TS 138.212: Section 5.4.1.3 - Interleaving of coded bits
|
||||
*/
|
||||
void nr_polar_rm_interleaving_cb(void *in, void *out, uint16_t E)
|
||||
{
|
||||
int T = ceil((sqrt(8 * E + 1) - 1) / 2);
|
||||
int v[T][T];
|
||||
int k = 0;
|
||||
uint64_t *in64 = (uint64_t *)in;
|
||||
for (int i = 0; i < T; i++) {
|
||||
for (int j = 0; j < T - i; j++) {
|
||||
if (k < E) {
|
||||
int k1 = k >> 6;
|
||||
int k2 = k - (k1 << 6);
|
||||
v[i][j] = (in64[k1] >> k2) & 1;
|
||||
} else {
|
||||
v[i][j] = -1;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
k = 0;
|
||||
uint64_t *out64 = (uint64_t *)out;
|
||||
memset(out64, 0, E >> 3);
|
||||
for (int j = 0; j < T; j++) {
|
||||
for (int i = 0; i < T - j; i++) {
|
||||
if (v[i][j] != -1) {
|
||||
int k1 = k >> 6;
|
||||
int k2 = k - (k1 << 6);
|
||||
out64[k1] |= (uint64_t)v[i][j] << k2;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void *in,void *out) __attribute__((always_inline));
|
||||
|
||||
static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void *in,void *out) {
|
||||
@@ -309,6 +348,10 @@ static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void
|
||||
for (int i=0; i<polarParams->encoderLength>>4; i++) {
|
||||
((uint16_t *)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]];
|
||||
}
|
||||
|
||||
if (polarParams->i_bil == 1) {
|
||||
nr_polar_rm_interleaving_cb(out, out, polarParams->encoderLength);
|
||||
}
|
||||
}
|
||||
|
||||
void build_polar_tables(t_nrPolar_params *polarParams) {
|
||||
@@ -344,28 +387,27 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
|
||||
|
||||
AssertFatal(polarParams->N == 512 || polarParams->N == 256 || polarParams->N == 128 || polarParams->N == 64, "N = %d, not done yet\n", polarParams->N);
|
||||
|
||||
// build G bit vectors for information bit positions and convert the bit as bytes tables in nr_polar_kronecker_power_matrices.c to 64 bit packed vectors.
|
||||
// keep only rows of G which correspond to information/crc bits
|
||||
polarParams->G_N_tab = (uint64_t **)calloc((polarParams->K + polarParams->n_pc),sizeof(int64_t *));
|
||||
int k=0;
|
||||
// build G bit vectors for information bit positions and convert the bit as bytes tables in nr_polar_kronecker_power_matrices.c to
|
||||
// 64 bit packed vectors.
|
||||
polarParams->G_N_tab = (uint64_t **)calloc(polarParams->N, sizeof(int64_t *));
|
||||
|
||||
for (int i=0; i<polarParams->N; i++) {
|
||||
if (polarParams->information_bit_pattern[i] > 0) {
|
||||
polarParams->G_N_tab[k] = (uint64_t *)memalign(32,(polarParams->N/64)*sizeof(uint64_t));
|
||||
memset((void *)polarParams->G_N_tab[k],0,(polarParams->N/64)*sizeof(uint64_t));
|
||||
for (int i = 0; i < polarParams->N; i++) {
|
||||
polarParams->G_N_tab[i] = (uint64_t *)memalign(32, (polarParams->N / 64) * sizeof(uint64_t));
|
||||
memset((void *)polarParams->G_N_tab[i], 0, (polarParams->N / 64) * sizeof(uint64_t));
|
||||
|
||||
for (int j=0; j<polarParams->N; j++)
|
||||
polarParams->G_N_tab[k][j/64] |= ((uint64_t)polarParams->G_N[i][j])<<(j&63);
|
||||
for (int j = 0; j < polarParams->N; j++)
|
||||
polarParams->G_N_tab[i][j / 64] |= ((uint64_t)polarParams->G_N[i][j]) << (j & 63);
|
||||
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
printf("Bit %d Selecting row %d of G : ",k,i);
|
||||
printf("Bit %d Selecting row %d of G : ", i, i);
|
||||
|
||||
for (int j=0; j<polarParams->N; j+=4) printf("%1x",polarParams->G_N[i][j]+(polarParams->G_N[i][j+1]*2)+(polarParams->G_N[i][j+2]*4)+(polarParams->G_N[i][j+3]*8));
|
||||
for (int j = 0; j < polarParams->N; j += 4)
|
||||
printf("%1x",
|
||||
polarParams->G_N[i][j] + (polarParams->G_N[i][j + 1] * 2) + (polarParams->G_N[i][j + 2] * 4)
|
||||
+ (polarParams->G_N[i][j + 3] * 8));
|
||||
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
#endif
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
// rate matching table
|
||||
@@ -452,6 +494,21 @@ void polar_encoder_fast(uint64_t *A,
|
||||
uint8_t aggregation_level) {
|
||||
|
||||
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, false);
|
||||
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
printf("polarParams->payloadBits = %i\n", polarParams->payloadBits);
|
||||
printf("polarParams->crcParityBits = %i\n", polarParams->crcParityBits);
|
||||
printf("polarParams->K = %i\n", polarParams->K);
|
||||
printf("polarParams->N = %i\n", polarParams->N);
|
||||
printf("polarParams->encoderLength = %i\n", polarParams->encoderLength);
|
||||
printf("polarParams->n_pc = %i\n", polarParams->n_pc);
|
||||
printf("polarParams->n_pc_wm = %i\n", polarParams->n_pc_wm);
|
||||
printf("polarParams->groupsize = %i\n", polarParams->groupsize);
|
||||
printf("polarParams->i_il = %i\n", polarParams->i_il);
|
||||
printf("polarParams->i_bil = %i\n", polarParams->i_bil);
|
||||
printf("polarParams->n_max = %i\n", polarParams->n_max);
|
||||
#endif
|
||||
|
||||
// AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
|
||||
AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
|
||||
AssertFatal(polarParams->payloadBits < 65, "payload bits = %d > 64, is not supported yet\n",polarParams->payloadBits);
|
||||
@@ -460,6 +517,23 @@ void polar_encoder_fast(uint64_t *A,
|
||||
AssertFatal(bitlen<129,"support for payloads <= 128 bits\n");
|
||||
// AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n");
|
||||
//int bitlen0=bitlen;
|
||||
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
int A_array = (bitlen + 63) >> 6;
|
||||
printf("\nTX\n");
|
||||
printf("a: ");
|
||||
for (int n = 0; n < bitlen; n++) {
|
||||
if (n % 4 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
int n1 = n >> 6;
|
||||
int n2 = n - (n1 << 6);
|
||||
int alen = n1 == 0 ? bitlen - (A_array << 6) : 64;
|
||||
printf("%lu", (A[A_array - 1 - n1] >> (alen - 1 - n2)) & 1);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
uint64_t tcrc=0;
|
||||
uint8_t offset = 0;
|
||||
|
||||
@@ -526,7 +600,6 @@ void polar_encoder_fast(uint64_t *A,
|
||||
tcrc = (uint64_t)((crcmask^(crc11(A128_flip,bitlen)>>21)))&0x7ff;
|
||||
}
|
||||
|
||||
int n;
|
||||
// this is number of quadwords in the bit string
|
||||
int quadwlen = (polarParams->K+63)/64;
|
||||
|
||||
@@ -536,27 +609,43 @@ void polar_encoder_fast(uint64_t *A,
|
||||
//??? b_{N'-1} b_{N'-2} ... b_{N'-A} b_{N'-A-1} ... b_{N'-A-Nparity} = a_{N-1} a_{N-2} ... a_{N-A} p_{N_parity-1} ... p_0
|
||||
uint64_t B[4]= {0};
|
||||
B[0] = (A[0] << polarParams->crcParityBits) | tcrc;
|
||||
for (n=1; n<quadwlen; n++)
|
||||
for (int n = 1; n < quadwlen; n++)
|
||||
if ((bitlen+63)/64 > n)
|
||||
B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits));
|
||||
else
|
||||
B[n] = (A[n-1]>>(64-polarParams->crcParityBits));
|
||||
|
||||
uint8_t *Bbyte = (uint8_t *)B;
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
int bitlen_B = bitlen + polarParams->crcParityBits;
|
||||
int B_array = (bitlen_B + 63) >> 6;
|
||||
int n_start = (B_array << 6) - bitlen_B;
|
||||
printf("b: ");
|
||||
for (int n = 0; n < bitlen_B; n++) {
|
||||
if (n % 4 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
int n1 = (n + n_start) >> 6;
|
||||
int n2 = (n + n_start) - (n1 << 6);
|
||||
printf("%lu", (B[B_array - 1 - n1] >> (63 - n2)) & 1);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
// for each byte of B, lookup in corresponding table for 64-bit word corresponding to that byte and its position
|
||||
// TS 38.212 - Section 5.3.1.1 Interleaving
|
||||
// For each byte of B, lookup in corresponding table for 64-bit word corresponding to that byte and its position
|
||||
uint64_t Cprime[4]= {0};
|
||||
if (polarParams->K<65)
|
||||
uint8_t *Bbyte = (uint8_t *)B;
|
||||
if (polarParams->K < 65) {
|
||||
Cprime[0] = polarParams->cprime_tab0[0][Bbyte[0]] |
|
||||
polarParams->cprime_tab0[1][Bbyte[1]] |
|
||||
polarParams->cprime_tab0[1][Bbyte[1]] |
|
||||
polarParams->cprime_tab0[2][Bbyte[2]] |
|
||||
polarParams->cprime_tab0[3][Bbyte[3]] |
|
||||
polarParams->cprime_tab0[4][Bbyte[4]] |
|
||||
polarParams->cprime_tab0[5][Bbyte[5]] |
|
||||
polarParams->cprime_tab0[6][Bbyte[6]] |
|
||||
polarParams->cprime_tab0[7][Bbyte[7]];
|
||||
else if (polarParams->K < 129) {
|
||||
for (int i=0; i<1+(polarParams->K/8); i++) {
|
||||
} else if (polarParams->K < 129) {
|
||||
for (int i = 0; i < 1 + (polarParams->K / 8); i++) {
|
||||
Cprime[0] |= polarParams->cprime_tab0[i][Bbyte[i]];
|
||||
Cprime[1] |= polarParams->cprime_tab1[i][Bbyte[i]];
|
||||
}
|
||||
@@ -567,165 +656,73 @@ void polar_encoder_fast(uint64_t *A,
|
||||
for (int i = 0; i < quadwlen; i++) printf("[polar_encoder_fast]C'[%d]= 0x%llx\n", i, (unsigned long long)(Cprime[i]));
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
|
||||
printf("Polar encoder: (N,K) : (%d,%d)\n",polarParams->N,polarParams->K);
|
||||
if (polarParams->K<65)
|
||||
printf("A %llx B %llx Cprime %llx (payload bits %d,crc %lx)\n",
|
||||
(unsigned long long)(A[0]&(((uint64_t)1<<bitlen)-1)),
|
||||
(unsigned long long)(B[0]),
|
||||
(unsigned long long)(Cprime[0]),
|
||||
polarParams->payloadBits,
|
||||
tcrc);
|
||||
else if (polarParams->K<129) {
|
||||
if (bitlen<64)
|
||||
printf("A %llx B %llx|%llx Cprime %llx|%llx (payload bits %d,crc %lx)\n",
|
||||
(unsigned long long)(A[0]&(((uint64_t)1<<bitlen)-1)),
|
||||
(unsigned long long)(B[1]),(unsigned long long)(B[0]),
|
||||
(unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]),
|
||||
polarParams->payloadBits,
|
||||
tcrc);
|
||||
else
|
||||
printf("A %llx|%llx B %llx|%llx Cprime %llx|%llx (payload bits %d,crc %x)\n",
|
||||
(unsigned long long)(A[1]&(((uint64_t)1<<(bitlen-64))-1)),(unsigned long long)(A[0]),
|
||||
(unsigned long long)(B[1]),(unsigned long long)(B[0]),
|
||||
(unsigned long long)(Cprime[1]),(unsigned long long)(Cprime[0]),
|
||||
polarParams->payloadBits,
|
||||
crc24c((uint8_t *)A,bitlen)>>8);
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
printf("c: ");
|
||||
for (int n = 0; n < bitlen_B; n++) {
|
||||
if (n % 4 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
int n1 = n >> 6;
|
||||
int n2 = n - (n1 << 6);
|
||||
printf("%lu", (Cprime[n1] >> n2) & 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
/* printf("Bbytes : %x.%x.%x.%x.%x.%x.%x.%x\n",Bbyte[0],Bbyte[1],Bbyte[2],Bbyte[3],Bbyte[4],Bbyte[5],Bbyte[6],Bbyte[7]);
|
||||
printf("%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",polarParams->cprime_tab[0][Bbyte[0]] ,
|
||||
polarParams->cprime_tab[1][Bbyte[1]] ,
|
||||
polarParams->cprime_tab[2][Bbyte[2]] ,
|
||||
polarParams->cprime_tab[3][Bbyte[3]] ,
|
||||
polarParams->cprime_tab[4][Bbyte[4]] ,
|
||||
polarParams->cprime_tab[5][Bbyte[5]] ,
|
||||
polarParams->cprime_tab[6][Bbyte[6]] ,
|
||||
polarParams->cprime_tab[7][Bbyte[7]]);*/
|
||||
// now do Gu product (here using 64-bit XORs, we can also do with SIMD after)
|
||||
// here we're reading out the bits LSB -> MSB, is this correct w.r.t. 3GPP ?
|
||||
uint64_t Cprime_i;
|
||||
/* printf("%llx Cprime_0 (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",Cprime_i,Cprime &1,
|
||||
polarParams->G_N_tab[0][0],
|
||||
polarParams->G_N_tab[0][1],
|
||||
polarParams->G_N_tab[0][2],
|
||||
polarParams->G_N_tab[0][3],
|
||||
polarParams->G_N_tab[0][4],
|
||||
polarParams->G_N_tab[0][5],
|
||||
polarParams->G_N_tab[0][6],
|
||||
polarParams->G_N_tab[0][7]);*/
|
||||
uint64_t D[8]= {0,0,0,0,0,0,0,0};
|
||||
int off=0;
|
||||
int len=polarParams->K;
|
||||
|
||||
if (polarParams->N==512) {
|
||||
for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) {
|
||||
for (int i=0; i<((len>63) ? 64 : len); i++) {
|
||||
Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11
|
||||
/*
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
|
||||
Cprime_i,off+i,(Cprime[j]>>i) &1,
|
||||
polarParams->G_N_tab[off+i][0],
|
||||
polarParams->G_N_tab[off+i][1],
|
||||
polarParams->G_N_tab[off+i][2],
|
||||
polarParams->G_N_tab[off+i][3],
|
||||
polarParams->G_N_tab[off+i][4],
|
||||
polarParams->G_N_tab[off+i][5],
|
||||
polarParams->G_N_tab[off+i][6],
|
||||
polarParams->G_N_tab[off+i][7]);
|
||||
#endif
|
||||
*/
|
||||
uint64_t *Gi=polarParams->G_N_tab[off+i];
|
||||
D[0] ^= (Cprime_i & Gi[0]);
|
||||
D[1] ^= (Cprime_i & Gi[1]);
|
||||
D[2] ^= (Cprime_i & Gi[2]);
|
||||
D[3] ^= (Cprime_i & Gi[3]);
|
||||
D[4] ^= (Cprime_i & Gi[4]);
|
||||
D[5] ^= (Cprime_i & Gi[5]);
|
||||
D[6] ^= (Cprime_i & Gi[6]);
|
||||
D[7] ^= (Cprime_i & Gi[7]);
|
||||
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
printf("D %llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",
|
||||
D[0],
|
||||
D[1],
|
||||
D[2],
|
||||
D[3],
|
||||
D[4],
|
||||
D[5],
|
||||
D[6],
|
||||
D[7]);
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t u[16] = {0};
|
||||
nr_polar_generate_u(u,
|
||||
Cprime,
|
||||
polarParams->information_bit_pattern,
|
||||
polarParams->parity_check_bit_pattern,
|
||||
polarParams->N,
|
||||
polarParams->n_pc);
|
||||
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
int N_array = polarParams->N >> 6;
|
||||
printf("u: ");
|
||||
for (int n = 0; n < polarParams->N; n++) {
|
||||
if (n % 4 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
int n1 = n >> 6;
|
||||
int n2 = n - (n1 << 6);
|
||||
printf("%lu", (u[N_array - 1 - n1] >> (63 - n2)) & 1);
|
||||
}
|
||||
else if (polarParams->N==256) {
|
||||
for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) {
|
||||
for (int i=0; i<((len>63) ? 64 : len); i++) {
|
||||
Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11
|
||||
/*
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
printf("%llx Cprime_%d (%llx) G %llx,%llx,%llx,%llx\n",
|
||||
Cprime_i,off+i,(Cprime[j]>>i) &1,
|
||||
polarParams->G_N_tab[off+i][0],
|
||||
polarParams->G_N_tab[off+i][1],
|
||||
polarParams->G_N_tab[off+i][2],
|
||||
polarParams->G_N_tab[off+i][3],
|
||||
#endif
|
||||
*/
|
||||
uint64_t *Gi=polarParams->G_N_tab[off+i];
|
||||
D[0] ^= (Cprime_i & Gi[0]);
|
||||
D[1] ^= (Cprime_i & Gi[1]);
|
||||
D[2] ^= (Cprime_i & Gi[2]);
|
||||
D[3] ^= (Cprime_i & Gi[3]);
|
||||
|
||||
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
printf("D %llx,%llx,%llx,%llx\n",
|
||||
D[0],
|
||||
D[1],
|
||||
D[2],
|
||||
D[3]);
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t D[8] = {0};
|
||||
nr_polar_uxG(D, u, (const uint64_t **)polarParams->G_N_tab, polarParams->N);
|
||||
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
printf("d: ");
|
||||
for (int n = 0; n < polarParams->N; n++) {
|
||||
if (n % 4 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
int n1 = n >> 6;
|
||||
int n2 = n - (n1 << 6);
|
||||
printf("%lu", (D[n1] >> n2) & 1);
|
||||
}
|
||||
else if (polarParams->N==128) {
|
||||
for (int j=0; j<(1+(polarParams->K>>6)); j++,off+=64,len-=64) {
|
||||
for (int i=0; i<((len>63) ? 64 : len); i++) {
|
||||
Cprime_i = -((Cprime[j]>>i)&1); // this converts bit 0 as, 0 => 0000x00, 1 => 1111x11
|
||||
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
printf("%lx Cprime_%d (%d+%d) (%llx) G %llx,%llx\n",
|
||||
Cprime_i,off+i,off,i,(Cprime[j]>>i) &1,
|
||||
polarParams->G_N_tab[off+i][0],
|
||||
polarParams->G_N_tab[off+i][1]);
|
||||
#endif
|
||||
|
||||
uint64_t *Gi=polarParams->G_N_tab[off+i];
|
||||
D[0] ^= (Cprime_i & Gi[0]);
|
||||
D[1] ^= (Cprime_i & Gi[1]);
|
||||
|
||||
|
||||
#ifdef DEBUG_POLAR_ENCODER
|
||||
printf("D %llx,%llx\n",
|
||||
D[0],
|
||||
D[1]);
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else if (polarParams->N == 64) {
|
||||
for (int i = 0; i < ((len > 63) ? 64 : len); i++) {
|
||||
Cprime_i = -((Cprime[0] >> i) & 1);
|
||||
D[0] ^= (Cprime_i & polarParams->G_N_tab[off + i][0]);
|
||||
}
|
||||
}
|
||||
|
||||
memset((void*)out,0,polarParams->encoderLength>>3);
|
||||
polar_rate_matching(polarParams,(void *)D, out);
|
||||
|
||||
polarReturn;
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
uint64_t *out64 = (uint64_t *)out;
|
||||
printf("rm:");
|
||||
for (int n = 0; n < polarParams->encoderLength; n++) {
|
||||
if (n % 4 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
int n1 = n >> 6;
|
||||
int n2 = n - (n1 << 6);
|
||||
printf("%lu", (out64[n1] >> n2) & 1);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
polarReturn;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,117 @@
|
||||
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||
|
||||
|
||||
// TS 38.212 - Section 5.3.1.2 Polar encoding
|
||||
void nr_polar_generate_u(uint64_t *u,
|
||||
const uint64_t *Cprime,
|
||||
const uint8_t *information_bit_pattern,
|
||||
const uint8_t *parity_check_bit_pattern,
|
||||
uint16_t N,
|
||||
uint8_t n_pc)
|
||||
{
|
||||
int N_array = N >> 6;
|
||||
int k = 0;
|
||||
|
||||
if (n_pc > 0) {
|
||||
uint64_t y0 = 0, y1 = 0, y2 = 0, y3 = 0, y4 = 0;
|
||||
|
||||
for (int n = 0; n < N; n++) {
|
||||
uint64_t yt = y0;
|
||||
y0 = y1;
|
||||
y1 = y2;
|
||||
y2 = y3;
|
||||
y3 = y4;
|
||||
y4 = yt;
|
||||
|
||||
if (information_bit_pattern[n] == 1) {
|
||||
int n1 = n >> 6;
|
||||
int n2 = n - (n1 << 6);
|
||||
if (parity_check_bit_pattern[n] == 1) {
|
||||
u[N_array - 1 - n1] |= y0 << (63 - n2);
|
||||
} else {
|
||||
int k1 = k >> 6;
|
||||
int k2 = k - (k1 << 6);
|
||||
uint64_t bit = (Cprime[k1] >> k2) & 1;
|
||||
u[N_array - 1 - n1] |= bit << (63 - n2);
|
||||
k++;
|
||||
y0 = y0 ^ (int)bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
for (int n = 0; n < N; n++) {
|
||||
if (information_bit_pattern[n] == 1) {
|
||||
int n1 = n >> 6;
|
||||
int n2 = n - (n1 << 6);
|
||||
int k1 = k >> 6;
|
||||
int k2 = k - (k1 << 6);
|
||||
uint64_t bit = (Cprime[k1] >> k2) & 1;
|
||||
u[N_array - 1 - n1] |= bit << (63 - n2);
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nr_polar_info_extraction_from_u(uint64_t *Cprime,
|
||||
const uint8_t *u,
|
||||
const uint8_t *information_bit_pattern,
|
||||
const uint8_t *parity_check_bit_pattern,
|
||||
uint16_t N,
|
||||
uint8_t n_pc)
|
||||
{
|
||||
int k = 0;
|
||||
|
||||
if (n_pc > 0) {
|
||||
for (int n = 0; n < N; n++) {
|
||||
if (information_bit_pattern[n] == 1) {
|
||||
if (parity_check_bit_pattern[n] == 0) {
|
||||
int k1 = k >> 6;
|
||||
int k2 = k - (k1 << 6);
|
||||
Cprime[k1] |= (uint64_t)u[n] << k2;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
for (int n = 0; n < N; n++) {
|
||||
if (information_bit_pattern[n] == 1) {
|
||||
int k1 = k >> 6;
|
||||
int k2 = k - (k1 << 6);
|
||||
Cprime[k1] |= (uint64_t)u[n] << k2;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nr_polar_uxG(uint64_t *D, const uint64_t *u, const uint64_t **G_N_tab, uint16_t N)
|
||||
{
|
||||
int N_array = N >> 6;
|
||||
|
||||
for (int n = 0; n < N; n++) {
|
||||
const uint64_t *Gn = G_N_tab[N - 1 - n];
|
||||
|
||||
int n_ones = 0;
|
||||
for (int a = 0; a < N_array; a++) {
|
||||
uint64_t uxG = u[a] & Gn[a];
|
||||
for (int m = 0; m < 64; m++) {
|
||||
if (((uxG >> m) & 1) == 1) {
|
||||
n_ones++;
|
||||
}
|
||||
}
|
||||
}
|
||||
uint64_t bit = n_ones % 2;
|
||||
|
||||
int n1 = n >> 6;
|
||||
int n2 = n - (n1 << 6);
|
||||
D[n1] |= bit << n2;
|
||||
}
|
||||
}
|
||||
|
||||
void nr_polar_bit_insertion(uint8_t *input,
|
||||
uint8_t *output,
|
||||
uint16_t N,
|
||||
@@ -138,14 +249,17 @@ void nr_polar_channel_interleaver_pattern(uint16_t *cip,
|
||||
|
||||
|
||||
void nr_polar_info_bit_pattern(uint8_t *ibp,
|
||||
int16_t *Q_I_N,
|
||||
int16_t *Q_F_N,
|
||||
uint16_t *J,
|
||||
const uint16_t *Q_0_Nminus1,
|
||||
uint16_t K,
|
||||
uint16_t N,
|
||||
uint16_t E,
|
||||
uint8_t n_PC)
|
||||
uint8_t *pcbp,
|
||||
int16_t *Q_I_N,
|
||||
int16_t *Q_F_N,
|
||||
int16_t *Q_PC_N,
|
||||
const uint16_t *J,
|
||||
const uint16_t *Q_0_Nminus1,
|
||||
uint16_t K,
|
||||
uint16_t N,
|
||||
uint16_t E,
|
||||
uint8_t n_PC,
|
||||
uint8_t n_pc_wm)
|
||||
{
|
||||
int16_t *Q_Ftmp_N = malloc(sizeof(int16_t) * (N + 1)); // Last element shows the final
|
||||
int16_t *Q_Itmp_N = malloc(sizeof(int16_t) * (N + 1)); // array index assigned a value.
|
||||
@@ -159,44 +273,44 @@ void nr_polar_info_bit_pattern(uint8_t *ibp,
|
||||
uint16_t limit, ind;
|
||||
|
||||
if (E < N) {
|
||||
if ((K / (double) E) <= (7.0 / 16)) { //puncturing
|
||||
if ((K / (double)E) <= (7.0 / 16)) { // puncturing
|
||||
for (int n = 0; n <= N - E - 1; n++) {
|
||||
ind = Q_Ftmp_N[N] + 1;
|
||||
Q_Ftmp_N[ind] = J[n];
|
||||
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
|
||||
ind = Q_Ftmp_N[N] + 1;
|
||||
Q_Ftmp_N[ind] = J[n];
|
||||
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
|
||||
}
|
||||
|
||||
if ((E / (double) N) >= (3.0 / 4)) {
|
||||
limit = ceil((double) (3 * N - 2 * E) / 4);
|
||||
for (int n = 0; n <= limit - 1; n++) {
|
||||
ind = Q_Ftmp_N[N] + 1;
|
||||
Q_Ftmp_N[ind] = n;
|
||||
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
|
||||
}
|
||||
if ((E / (double)N) >= (3.0 / 4)) {
|
||||
limit = ceil((double)(3 * N - 2 * E) / 4);
|
||||
for (int n = 0; n <= limit - 1; n++) {
|
||||
ind = Q_Ftmp_N[N] + 1;
|
||||
Q_Ftmp_N[ind] = n;
|
||||
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
|
||||
}
|
||||
} else {
|
||||
limit = ceil((double) (9 * N - 4 * E) / 16);
|
||||
for (int n = 0; n <= limit - 1; n++) {
|
||||
ind = Q_Ftmp_N[N] + 1;
|
||||
Q_Ftmp_N[ind] = n;
|
||||
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
|
||||
}
|
||||
limit = ceil((double)(9 * N - 4 * E) / 16);
|
||||
for (int n = 0; n <= limit - 1; n++) {
|
||||
ind = Q_Ftmp_N[N] + 1;
|
||||
Q_Ftmp_N[ind] = n;
|
||||
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
|
||||
}
|
||||
}
|
||||
} else { //shortening
|
||||
} else { // shortening
|
||||
for (int n = E; n <= N - 1; n++) {
|
||||
ind = Q_Ftmp_N[N] + 1;
|
||||
Q_Ftmp_N[ind] = J[n];
|
||||
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
|
||||
ind = Q_Ftmp_N[N] + 1;
|
||||
Q_Ftmp_N[ind] = J[n];
|
||||
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Q_I,tmp_N = Q_0_N-1 \ Q_F,tmp_N
|
||||
// Q_I,tmp_N = Q_0_N-1 \ Q_F,tmp_N
|
||||
for (int n = 0; n <= N - 1; n++) {
|
||||
flag = 1;
|
||||
for (int m = 0; m <= Q_Ftmp_N[N]; m++) {
|
||||
if (Q_0_Nminus1[n] == Q_Ftmp_N[m]) {
|
||||
flag = 0;
|
||||
break;
|
||||
flag = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
@@ -205,19 +319,26 @@ void nr_polar_info_bit_pattern(uint8_t *ibp,
|
||||
}
|
||||
}
|
||||
|
||||
//Q_I_N comprises (K+n_PC) most reliable bit indices in Q_I,tmp_N
|
||||
// Q_I_N comprises (K+n_PC) most reliable bit indices in Q_I,tmp_N
|
||||
for (int n = 0; n <= (K + n_PC) - 1; n++) {
|
||||
ind = Q_Itmp_N[N] + n - ((K + n_PC) - 1);
|
||||
Q_I_N[n] = Q_Itmp_N[ind];
|
||||
}
|
||||
|
||||
//Q_F_N = Q_0_N-1 \ Q_I_N
|
||||
if (n_PC > 0) {
|
||||
AssertFatal(n_pc_wm == 0, "Q_PC_N computation for n_pc_wm = %i is not implemented yet!\n", n_pc_wm);
|
||||
for (int n = 0; n < n_PC - n_pc_wm; n++) {
|
||||
Q_PC_N[n] = Q_I_N[n];
|
||||
}
|
||||
}
|
||||
|
||||
// Q_F_N = Q_0_N-1 \ Q_I_N
|
||||
for (int n = 0; n <= N - 1; n++) {
|
||||
flag = 1;
|
||||
for (int m = 0; m <= (K + n_PC) - 1; m++) {
|
||||
if (Q_0_Nminus1[n] == Q_I_N[m]) {
|
||||
flag = 0;
|
||||
break;
|
||||
flag = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
@@ -226,16 +347,25 @@ void nr_polar_info_bit_pattern(uint8_t *ibp,
|
||||
}
|
||||
}
|
||||
|
||||
//Information Bit Pattern
|
||||
// Information and Parity Chack Bit Pattern
|
||||
for (int n = 0; n <= N - 1; n++) {
|
||||
ibp[n] = 0;
|
||||
|
||||
ibp[n] = 0;
|
||||
for (int m = 0; m <= (K + n_PC) - 1; m++) {
|
||||
if (n == Q_I_N[m]) {
|
||||
ibp[n] = 1;
|
||||
break;
|
||||
ibp[n] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pcbp[n] = 0;
|
||||
for (int m = 0; m < n_PC - n_pc_wm; m++) {
|
||||
if (n == Q_PC_N[m]) {
|
||||
pcbp[n] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
free(Q_Ftmp_N);
|
||||
@@ -325,23 +455,75 @@ void nr_polar_rate_matching(double *input,
|
||||
}
|
||||
}
|
||||
|
||||
void nr_polar_rate_matching_int16(int16_t *input,
|
||||
int16_t *output,
|
||||
uint16_t *rmp,
|
||||
uint16_t K,
|
||||
uint16_t N,
|
||||
uint16_t E)
|
||||
/*
|
||||
* De-interleaving of coded bits implementation
|
||||
* TS 138.212: Section 5.4.1.3 - Interleaving of coded bits
|
||||
*/
|
||||
void nr_polar_rm_deinterleaving_cb(const int16_t *in, int16_t *out, const uint16_t E)
|
||||
{
|
||||
if (E>=N) { //repetition
|
||||
memset((void*)output,0,N*sizeof(int16_t));
|
||||
for (int i=0; i<=E-1; i++) output[rmp[i]]+=input[i];
|
||||
} else {
|
||||
if ( (K/(double)E) <= (7.0/16) ) memset((void*)output,0,N*sizeof(int16_t)); //puncturing
|
||||
else { //shortening
|
||||
for (int i=0; i<=N-1; i++) output[i]=32767;//instead of INFINITY, to prevent [-Woverflow]
|
||||
int T = ceil((sqrt(8 * E + 1) - 1) / 2);
|
||||
int v_tab[T][T];
|
||||
int k = 0;
|
||||
for (int i = 0; i < T; i++) {
|
||||
memset(v_tab[i], 0, T * sizeof(int));
|
||||
for (int j = 0; j < T - i; j++) {
|
||||
if (k < E) {
|
||||
v_tab[i][j] = k + 1;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<=E-1; i++) output[rmp[i]]=input[i];
|
||||
|
||||
int v[T][T];
|
||||
k = 0;
|
||||
for (int j = 0; j < T; j++) {
|
||||
for (int i = 0; i < T - j; i++) {
|
||||
if (k < E && v_tab[i][j] != 0) {
|
||||
v[i][j] = in[k];
|
||||
k++;
|
||||
} else {
|
||||
v[i][j] = INT_MAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
k = 0;
|
||||
memset(out, 0, E * sizeof(int16_t));
|
||||
for (int i = 0; i < T; i++) {
|
||||
for (int j = 0; j < T - i; j++) {
|
||||
if (v[i][j] != INT_MAX) {
|
||||
out[k] = v[i][j];
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nr_polar_rate_matching_int16(int16_t *input,
|
||||
int16_t *output,
|
||||
const uint16_t *rmp,
|
||||
const uint16_t K,
|
||||
const uint16_t N,
|
||||
const uint16_t E,
|
||||
const uint8_t i_bil)
|
||||
{
|
||||
if (i_bil == 1) {
|
||||
nr_polar_rm_deinterleaving_cb(input, input, E);
|
||||
}
|
||||
|
||||
if (E >= N) { // repetition
|
||||
memset((void *)output, 0, N * sizeof(int16_t));
|
||||
for (int i = 0; i <= E - 1; i++)
|
||||
output[rmp[i]] += input[i];
|
||||
} else {
|
||||
if ((K / (double)E) <= (7.0 / 16))
|
||||
memset((void *)output, 0, N * sizeof(int16_t)); // puncturing
|
||||
else { // shortening
|
||||
for (int i = 0; i <= N - 1; i++)
|
||||
output[i] = 32767; // instead of INFINITY, to prevent [-Woverflow]
|
||||
}
|
||||
|
||||
for (int i = 0; i <= E - 1; i++)
|
||||
output[rmp[i]] = input[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,9 +49,9 @@ static void nr_polar_delete_list(t_nrPolar_params * polarParams) {
|
||||
|
||||
delete_decoder_tree(polarParams);
|
||||
//From build_polar_tables()
|
||||
for (int k=0; k < polarParams->K + polarParams->n_pc; k++)
|
||||
if (polarParams->G_N_tab[k])
|
||||
free(polarParams->G_N_tab[k]);
|
||||
for (int n=0; n < polarParams->N; n++)
|
||||
if (polarParams->G_N_tab[n])
|
||||
free(polarParams->G_N_tab[n]);
|
||||
free(polarParams->G_N_tab);
|
||||
free(polarParams->rm_tab);
|
||||
if (polarParams->crc_generator_matrix)
|
||||
@@ -71,6 +71,7 @@ static void nr_polar_delete_list(t_nrPolar_params * polarParams) {
|
||||
free(polarParams->deinterleaving_pattern);
|
||||
free(polarParams->rate_matching_pattern);
|
||||
free(polarParams->information_bit_pattern);
|
||||
free(polarParams->parity_check_bit_pattern);
|
||||
free(polarParams->Q_I_N);
|
||||
free(polarParams->Q_F_N);
|
||||
free(polarParams->Q_PC_N);
|
||||
@@ -234,6 +235,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
|
||||
newPolarInitNode->N,
|
||||
newPolarInitNode->encoderLength);
|
||||
newPolarInitNode->information_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N);
|
||||
newPolarInitNode->parity_check_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N);
|
||||
newPolarInitNode->Q_I_N = malloc(sizeof(int16_t) * (newPolarInitNode->K + newPolarInitNode->n_pc));
|
||||
newPolarInitNode->Q_F_N = malloc( sizeof(int16_t) * (newPolarInitNode->N + 1)); // Last element shows the final array index assigned a value.
|
||||
newPolarInitNode->Q_PC_N = malloc( sizeof(int16_t) * (newPolarInitNode->n_pc));
|
||||
@@ -242,14 +244,18 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
|
||||
newPolarInitNode->Q_F_N[i] = -1; // Empty array.
|
||||
|
||||
nr_polar_info_bit_pattern(newPolarInitNode->information_bit_pattern,
|
||||
newPolarInitNode->parity_check_bit_pattern,
|
||||
newPolarInitNode->Q_I_N,
|
||||
newPolarInitNode->Q_F_N,
|
||||
newPolarInitNode->Q_PC_N,
|
||||
J,
|
||||
newPolarInitNode->Q_0_Nminus1,
|
||||
newPolarInitNode->K,
|
||||
newPolarInitNode->N,
|
||||
newPolarInitNode->encoderLength,
|
||||
newPolarInitNode->n_pc);
|
||||
newPolarInitNode->n_pc,
|
||||
newPolarInitNode->n_pc_wm);
|
||||
|
||||
// sort the Q_I_N array in ascending order (first K positions)
|
||||
qsort((void *)newPolarInitNode->Q_I_N,newPolarInitNode->K,sizeof(int16_t),intcmp);
|
||||
newPolarInitNode->channel_interleaver_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
|
||||
|
||||
@@ -149,16 +149,16 @@ void init_nr_prs_ue_vars(PHY_VARS_NR_UE *ue)
|
||||
// PRS vars init
|
||||
for(int idx = 0; idx < NR_MAX_PRS_COMB_SIZE; idx++)
|
||||
{
|
||||
prs_vars[idx] = (NR_UE_PRS *)malloc16_clear(sizeof(NR_UE_PRS));
|
||||
prs_vars[idx] = malloc16_clear(sizeof(NR_UE_PRS));
|
||||
// PRS channel estimates
|
||||
|
||||
for(int k = 0; k < NR_MAX_PRS_RESOURCES_PER_SET; k++)
|
||||
{
|
||||
prs_vars[idx]->prs_resource[k].prs_meas = (prs_meas_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(prs_meas_t *) );
|
||||
prs_vars[idx]->prs_resource[k].prs_meas = malloc16_clear(fp->nb_antennas_rx * sizeof(prs_meas_t *));
|
||||
AssertFatal((prs_vars[idx]->prs_resource[k].prs_meas!=NULL), "%s: PRS measurements malloc failed for gNB_id %d\n", __FUNCTION__, idx);
|
||||
|
||||
for (int j=0; j<fp->nb_antennas_rx; j++) {
|
||||
prs_vars[idx]->prs_resource[k].prs_meas[j] = (prs_meas_t *)malloc16_clear(sizeof(prs_meas_t) );
|
||||
prs_vars[idx]->prs_resource[k].prs_meas[j] = malloc16_clear(sizeof(prs_meas_t));
|
||||
AssertFatal((prs_vars[idx]->prs_resource[k].prs_meas[j]!=NULL), "%s: PRS measurements malloc failed for gNB_id %d, rx_ant %d\n", __FUNCTION__, idx, j);
|
||||
}
|
||||
}
|
||||
@@ -168,23 +168,23 @@ void init_nr_prs_ue_vars(PHY_VARS_NR_UE *ue)
|
||||
RCconfig_nrUE_prs(ue);
|
||||
|
||||
//PRS sequence init
|
||||
ue->nr_gold_prs = (uint32_t *****)malloc16(ue->prs_active_gNBs*sizeof(uint32_t ****));
|
||||
ue->nr_gold_prs = malloc16(ue->prs_active_gNBs * sizeof(uint32_t ****));
|
||||
uint32_t *****prs = ue->nr_gold_prs;
|
||||
AssertFatal(prs!=NULL, "%s: positioning reference signal malloc failed\n", __FUNCTION__);
|
||||
for (int gnb = 0; gnb < ue->prs_active_gNBs; gnb++) {
|
||||
prs[gnb] = (uint32_t ****)malloc16(ue->prs_vars[gnb]->NumPRSResources*sizeof(uint32_t ***));
|
||||
prs[gnb] = malloc16(ue->prs_vars[gnb]->NumPRSResources * sizeof(uint32_t ***));
|
||||
AssertFatal(prs[gnb]!=NULL, "%s: positioning reference signal for gnb %d - malloc failed\n", __FUNCTION__, gnb);
|
||||
|
||||
for (int rsc = 0; rsc < ue->prs_vars[gnb]->NumPRSResources; rsc++) {
|
||||
prs[gnb][rsc] = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
|
||||
prs[gnb][rsc] = malloc16(fp->slots_per_frame * sizeof(uint32_t **));
|
||||
AssertFatal(prs[gnb][rsc]!=NULL, "%s: positioning reference signal for gnb %d rsc %d- malloc failed\n", __FUNCTION__, gnb, rsc);
|
||||
|
||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
||||
prs[gnb][rsc][slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
|
||||
prs[gnb][rsc][slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t *));
|
||||
AssertFatal(prs[gnb][rsc][slot]!=NULL, "%s: positioning reference signal for gnb %d rsc %d slot %d - malloc failed\n", __FUNCTION__, gnb, rsc, slot);
|
||||
|
||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
||||
prs[gnb][rsc][slot][symb] = (uint32_t *)malloc16(NR_MAX_PRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
|
||||
prs[gnb][rsc][slot][symb] = malloc16(NR_MAX_PRS_INIT_LENGTH_DWORD * sizeof(uint32_t));
|
||||
AssertFatal(prs[gnb][rsc][slot][symb]!=NULL, "%s: positioning reference signal for gnb %d rsc %d slot %d symbol %d - malloc failed\n", __FUNCTION__, gnb, rsc, slot, symb);
|
||||
} // for symb
|
||||
} // for slot
|
||||
@@ -251,19 +251,19 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
|
||||
// ceil(((NB_RB*6(k)*2(QPSK)/32) // 3 RE *2(QPSK)
|
||||
int pusch_dmrs_init_length = ((fp->N_RB_UL*12)>>5)+1;
|
||||
ue->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
|
||||
ue->nr_gold_pusch_dmrs = malloc16(fp->slots_per_frame * sizeof(uint32_t ***));
|
||||
uint32_t ****pusch_dmrs = ue->nr_gold_pusch_dmrs;
|
||||
|
||||
for (slot=0; slot<fp->slots_per_frame; slot++) {
|
||||
pusch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **));
|
||||
pusch_dmrs[slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t **));
|
||||
AssertFatal(pusch_dmrs[slot]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d - malloc failed\n", slot);
|
||||
|
||||
for (symb=0; symb<fp->symbols_per_slot; symb++) {
|
||||
pusch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_NB_NSCID*sizeof(uint32_t *));
|
||||
pusch_dmrs[slot][symb] = malloc16(NR_NB_NSCID * sizeof(uint32_t *));
|
||||
AssertFatal(pusch_dmrs[slot][symb]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
|
||||
|
||||
for (int q=0; q<NR_NB_NSCID; q++) {
|
||||
pusch_dmrs[slot][symb][q] = (uint32_t *)malloc16(pusch_dmrs_init_length*sizeof(uint32_t));
|
||||
pusch_dmrs[slot][symb][q] = malloc16(pusch_dmrs_init_length * sizeof(uint32_t));
|
||||
AssertFatal(pusch_dmrs[slot][symb][q]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d symbol %d nscid %d - malloc failed\n", slot, symb, q);
|
||||
}
|
||||
}
|
||||
@@ -291,36 +291,34 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
ue->tx_power_dBm[i]=-127;
|
||||
|
||||
// init TX buffers
|
||||
common_vars->txdata = (c16_t **)malloc16(fp->nb_antennas_tx*sizeof(c16_t *));
|
||||
common_vars->txdataF = (c16_t **)malloc16(fp->nb_antennas_tx*sizeof(c16_t *));
|
||||
common_vars->txData = malloc16(fp->nb_antennas_tx * sizeof(c16_t *));
|
||||
|
||||
for (i=0; i<fp->nb_antennas_tx; i++) {
|
||||
common_vars->txdata[i] = (c16_t *)malloc16_clear((fp->samples_per_frame) * sizeof(c16_t));
|
||||
common_vars->txdataF[i] = (c16_t *)malloc16_clear((fp->samples_per_frame) * sizeof(c16_t));
|
||||
common_vars->txData[i] = malloc16_clear((fp->samples_per_frame) * sizeof(c16_t));
|
||||
}
|
||||
|
||||
// init RX buffers
|
||||
common_vars->rxdata = (c16_t **)malloc16( fp->nb_antennas_rx*sizeof(c16_t *));
|
||||
common_vars->rxdataF = (c16_t **)malloc16( fp->nb_antennas_rx*sizeof(c16_t *));
|
||||
common_vars->rxdata = malloc16(fp->nb_antennas_rx * sizeof(c16_t *));
|
||||
common_vars->rxdataF = malloc16(fp->nb_antennas_rx * sizeof(c16_t *));
|
||||
|
||||
for (i=0; i<fp->nb_antennas_rx; i++) {
|
||||
common_vars->rxdata[i] = (c16_t *)malloc16_clear((2 * (fp->samples_per_frame)+fp->ofdm_symbol_size) * sizeof(c16_t));
|
||||
common_vars->rxdataF[i] = (c16_t *)malloc16_clear((2 * (fp->samples_per_frame)+fp->ofdm_symbol_size) * sizeof(c16_t));
|
||||
common_vars->rxdata[i] = malloc16_clear((2 * (fp->samples_per_frame) + fp->ofdm_symbol_size) * sizeof(c16_t));
|
||||
common_vars->rxdataF[i] = malloc16_clear((2 * (fp->samples_per_frame) + fp->ofdm_symbol_size) * sizeof(c16_t));
|
||||
}
|
||||
|
||||
// ceil(((NB_RB<<1)*3)/32) // 3 RE *2(QPSK)
|
||||
int pdcch_dmrs_init_length = (((fp->N_RB_DL<<1)*3)>>5)+1;
|
||||
//PDCCH DMRS init (gNB offset = 0)
|
||||
ue->nr_gold_pdcch[0] = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
|
||||
ue->nr_gold_pdcch[0] = malloc16(fp->slots_per_frame * sizeof(uint32_t **));
|
||||
uint32_t ***pdcch_dmrs = ue->nr_gold_pdcch[0];
|
||||
AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n");
|
||||
|
||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
||||
pdcch_dmrs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
|
||||
pdcch_dmrs[slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t *));
|
||||
AssertFatal(pdcch_dmrs[slot]!=NULL, "NR init: pdcch_dmrs for slot %d - malloc failed\n", slot);
|
||||
|
||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
||||
pdcch_dmrs[slot][symb] = (uint32_t *)malloc16(pdcch_dmrs_init_length*sizeof(uint32_t));
|
||||
pdcch_dmrs[slot][symb] = malloc16(pdcch_dmrs_init_length * sizeof(uint32_t));
|
||||
AssertFatal(pdcch_dmrs[slot][symb]!=NULL, "NR init: pdcch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
|
||||
}
|
||||
}
|
||||
@@ -329,19 +327,19 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
int pdsch_dmrs_init_length = ((fp->N_RB_DL*12)>>5)+1;
|
||||
|
||||
//PDSCH DMRS init (eNB offset = 0)
|
||||
ue->nr_gold_pdsch[0] = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
|
||||
ue->nr_gold_pdsch[0] = malloc16(fp->slots_per_frame * sizeof(uint32_t ***));
|
||||
uint32_t ****pdsch_dmrs = ue->nr_gold_pdsch[0];
|
||||
|
||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
||||
pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **));
|
||||
pdsch_dmrs[slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t **));
|
||||
AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot);
|
||||
|
||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
||||
pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_NB_NSCID*sizeof(uint32_t *));
|
||||
pdsch_dmrs[slot][symb] = malloc16(NR_NB_NSCID * sizeof(uint32_t *));
|
||||
AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
|
||||
|
||||
for (int q=0; q<NR_NB_NSCID; q++) {
|
||||
pdsch_dmrs[slot][symb][q] = (uint32_t *)malloc16(pdsch_dmrs_init_length*sizeof(uint32_t));
|
||||
pdsch_dmrs[slot][symb][q] = malloc16(pdsch_dmrs_init_length * sizeof(uint32_t));
|
||||
AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d nscid %d - malloc failed\n", slot, symb, q);
|
||||
}
|
||||
}
|
||||
@@ -349,10 +347,10 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
|
||||
// DLSCH
|
||||
for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
|
||||
prach_vars[gNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH));
|
||||
csiim_vars[gNB_id] = (NR_UE_CSI_IM *)malloc16_clear(sizeof(NR_UE_CSI_IM));
|
||||
csirs_vars[gNB_id] = (NR_UE_CSI_RS *)malloc16_clear(sizeof(NR_UE_CSI_RS));
|
||||
srs_vars[gNB_id] = (NR_UE_SRS *)malloc16_clear(sizeof(NR_UE_SRS));
|
||||
prach_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_PRACH));
|
||||
csiim_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_CSI_IM));
|
||||
csirs_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_CSI_RS));
|
||||
srs_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_SRS));
|
||||
|
||||
csiim_vars[gNB_id]->active = false;
|
||||
csirs_vars[gNB_id]->active = false;
|
||||
@@ -360,24 +358,23 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
|
||||
// ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32)
|
||||
int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1;
|
||||
ue->nr_csi_info = (nr_csi_info_t *)malloc16_clear(sizeof(nr_csi_info_t));
|
||||
ue->nr_csi_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame * sizeof(uint32_t **));
|
||||
ue->nr_csi_info = malloc16_clear(sizeof(nr_csi_info_t));
|
||||
ue->nr_csi_info->nr_gold_csi_rs = malloc16(fp->slots_per_frame * sizeof(uint32_t **));
|
||||
AssertFatal(ue->nr_csi_info->nr_gold_csi_rs != NULL, "NR init: csi reference signal malloc failed\n");
|
||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
||||
ue->nr_csi_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot * sizeof(uint32_t *));
|
||||
ue->nr_csi_info->nr_gold_csi_rs[slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t *));
|
||||
AssertFatal(ue->nr_csi_info->nr_gold_csi_rs[slot] != NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot);
|
||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
||||
ue->nr_csi_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length * sizeof(uint32_t));
|
||||
ue->nr_csi_info->nr_gold_csi_rs[slot][symb] = malloc16(csi_dmrs_init_length * sizeof(uint32_t));
|
||||
AssertFatal(ue->nr_csi_info->nr_gold_csi_rs[slot][symb] != NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
|
||||
}
|
||||
}
|
||||
ue->nr_csi_info->csi_rs_generated_signal = (int32_t **)malloc16(NR_MAX_NB_PORTS * sizeof(int32_t *) );
|
||||
ue->nr_csi_info->csi_rs_generated_signal = malloc16(NR_MAX_NB_PORTS * sizeof(int32_t *));
|
||||
for (i=0; i<NR_MAX_NB_PORTS; i++) {
|
||||
ue->nr_csi_info->csi_rs_generated_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
|
||||
ue->nr_csi_info->csi_rs_generated_signal[i] = malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
|
||||
}
|
||||
|
||||
ue->nr_srs_info = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t));
|
||||
|
||||
ue->nr_srs_info = malloc16_clear(sizeof(nr_srs_info_t));
|
||||
}
|
||||
|
||||
ue->init_averaging = 1;
|
||||
@@ -411,12 +408,10 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
NR_UE_COMMON* common_vars = &ue->common_vars;
|
||||
|
||||
for (int i = 0; i < fp->nb_antennas_tx; i++) {
|
||||
free_and_zero(common_vars->txdata[i]);
|
||||
free_and_zero(common_vars->txdataF[i]);
|
||||
free_and_zero(common_vars->txData[i]);
|
||||
}
|
||||
|
||||
free_and_zero(common_vars->txdata);
|
||||
free_and_zero(common_vars->txdataF);
|
||||
free_and_zero(common_vars->txData);
|
||||
|
||||
for (int i = 0; i < fp->nb_antennas_rx; i++) {
|
||||
free_and_zero(common_vars->rxdata[i]);
|
||||
|
||||
@@ -173,7 +173,7 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL)
|
||||
N_RB_DL,fp->first_carrier_offset,fp->nb_prefix_samples,fp->nb_prefix_samples0, fp->ofdm_symbol_size);
|
||||
}
|
||||
|
||||
uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp)
|
||||
uint32_t get_samples_per_slot(int slot, const NR_DL_FRAME_PARMS *fp)
|
||||
{
|
||||
uint32_t samp_count;
|
||||
|
||||
@@ -185,7 +185,7 @@ uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp)
|
||||
return samp_count;
|
||||
}
|
||||
|
||||
uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, NR_DL_FRAME_PARMS* fp)
|
||||
uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, const NR_DL_FRAME_PARMS *fp)
|
||||
{
|
||||
uint32_t slot_idx = 0;
|
||||
int samples_till_the_slot = fp->get_samples_per_slot(slot_idx,fp)-1;
|
||||
@@ -198,7 +198,7 @@ uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, NR_DL_FRAME_PA
|
||||
return slot_idx;
|
||||
}
|
||||
|
||||
uint32_t get_samples_slot_timestamp(int slot, NR_DL_FRAME_PARMS* fp, uint8_t sl_ahead)
|
||||
uint32_t get_samples_slot_timestamp(int slot, const NR_DL_FRAME_PARMS *fp, uint8_t sl_ahead)
|
||||
{
|
||||
uint32_t samp_count = 0;
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ void PHY_ofdm_mod(int *input,
|
||||
|
||||
|
||||
void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms);
|
||||
void nr_normal_prefix_mod(c16_t *txdataF, c16_t *txdata, uint8_t nsymb, NR_DL_FRAME_PARMS *frame_parms, uint32_t slot);
|
||||
void nr_normal_prefix_mod(c16_t *txdataF, c16_t *txdata, uint8_t nsymb, const NR_DL_FRAME_PARMS *frame_parms, uint32_t slot);
|
||||
|
||||
void do_OFDM_mod(c16_t **txdataF, c16_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
|
||||
@@ -108,9 +108,9 @@ int nr_beam_precoding(c16_t **txdataF,
|
||||
int offset
|
||||
);
|
||||
|
||||
void apply_nr_rotation_TX(NR_DL_FRAME_PARMS *fp,
|
||||
void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
|
||||
c16_t *txdataF,
|
||||
c16_t *symbol_rotation,
|
||||
const c16_t *symbol_rotation,
|
||||
int slot,
|
||||
int nb_rb,
|
||||
int first_symbol,
|
||||
|
||||
@@ -64,7 +64,7 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA
|
||||
|
||||
}
|
||||
|
||||
void nr_normal_prefix_mod(c16_t *txdataF, c16_t *txdata, uint8_t nsymb, NR_DL_FRAME_PARMS *frame_parms, uint32_t slot)
|
||||
void nr_normal_prefix_mod(c16_t *txdataF, c16_t *txdata, uint8_t nsymb, const NR_DL_FRAME_PARMS *frame_parms, uint32_t slot)
|
||||
{
|
||||
// This function works only slot wise. For more generic symbol generation refer nr_feptx0()
|
||||
if (frame_parms->numerology_index != 0) { // case where numerology != 0
|
||||
@@ -334,9 +334,9 @@ void do_OFDM_mod(c16_t **txdataF, c16_t **txdata, uint32_t frame,uint16_t next_s
|
||||
|
||||
}
|
||||
|
||||
void apply_nr_rotation_TX(NR_DL_FRAME_PARMS *fp,
|
||||
void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
|
||||
c16_t *txdataF,
|
||||
c16_t *symbol_rotation,
|
||||
const c16_t *symbol_rotation,
|
||||
int slot,
|
||||
int nb_rb,
|
||||
int first_symbol,
|
||||
@@ -347,7 +347,7 @@ void apply_nr_rotation_TX(NR_DL_FRAME_PARMS *fp,
|
||||
symbol_rotation += symb_offset;
|
||||
|
||||
for (int sidx = first_symbol; sidx < first_symbol + nsymb; sidx++) {
|
||||
c16_t *this_rotation = symbol_rotation + sidx;
|
||||
const c16_t *this_rotation = symbol_rotation + sidx;
|
||||
c16_t *this_symbol = (txdataF) + sidx * fp->ofdm_symbol_size;
|
||||
|
||||
LOG_D(PHY,"Rotating symbol %d, slot %d, symbol_subframe_index %d (%d,%d)\n",
|
||||
|
||||
@@ -75,11 +75,11 @@ void free_context_sss_nr(void);
|
||||
void insert_sss_nr(int16_t *sss_time,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
int rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
int32_t *tot_metric,
|
||||
uint8_t *phase_max,
|
||||
int *freq_offset_sss,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
|
||||
bool rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
int32_t *tot_metric,
|
||||
uint8_t *phase_max,
|
||||
int *freq_offset_sss,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
|
||||
#endif /* SSS_NR_H */
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
* \warning
|
||||
*/
|
||||
|
||||
extern int16_t nr_ru[2 * 839]; // quantized roots of unity
|
||||
extern c16_t nr_ru[839]; // quantized roots of unity
|
||||
extern uint16_t nr_du[838];
|
||||
|
||||
static const char* const prachfmt[] = {"0", "1", "2", "3", "A1", "A2", "A3", "B1", "B4", "C0", "C2", "A1/B1", "A2/B2", "A3/B3"};
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "T.h"
|
||||
int16_t nr_ru[2 * 839]; // quantized roots of unity
|
||||
c16_t nr_ru[839]; // quantized roots of unity
|
||||
static uint32_t nr_ZC_inv[839]; // multiplicative inverse for roots u
|
||||
uint16_t nr_du[838];
|
||||
|
||||
@@ -97,11 +97,8 @@ void nr_fill_du(uint16_t N_ZC, const uint16_t *prach_root_sequence_map)
|
||||
|
||||
}
|
||||
|
||||
void compute_nr_prach_seq(uint8_t short_sequence,
|
||||
uint8_t num_sequences,
|
||||
uint8_t rootSequenceIndex,
|
||||
uint32_t X_u[64][839]){
|
||||
|
||||
void compute_nr_prach_seq(uint8_t short_sequence, uint8_t num_sequences, uint8_t rootSequenceIndex, c16_t X_u[64][839])
|
||||
{
|
||||
// Compute DFT of x_u => X_u[k] = x_u(inv(u)*k)^* X_u[k] = exp(j\pi u*inv(u)*k*(inv(u)*k+1)/N_ZC)
|
||||
unsigned int k,inv_u,i;
|
||||
int N_ZC;
|
||||
@@ -147,7 +144,7 @@ void compute_nr_prach_seq(uint8_t short_sequence,
|
||||
|
||||
for (k=0; k<N_ZC; k++) {
|
||||
// multiply by inverse of 2 (required since ru is exp[j 2\pi n])
|
||||
X_u[i][k] = ((uint32_t*)nr_ru)[(((k*(1+(inv_u*k)))%N_ZC)*nr_ZC_inv[2])%N_ZC];
|
||||
X_u[i][k] = nr_ru[(((k * (1 + (inv_u * k))) % N_ZC) * nr_ZC_inv[2]) % N_ZC];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,12 +178,12 @@ void init_nr_prach_tables(int N_ZC)
|
||||
|
||||
// Compute quantized roots of unity
|
||||
for (i=0; i<N_ZC; i++) {
|
||||
nr_ru[i<<1] = (int16_t)(floor(32767.0*cos(2*M_PI*(double)i/N_ZC)));
|
||||
nr_ru[1+(i<<1)] = (int16_t)(floor(32767.0*sin(2*M_PI*(double)i/N_ZC)));
|
||||
nr_ru[i].r = (int16_t)(floor(32767.0 * cos(2 * M_PI * (double)i / N_ZC)));
|
||||
nr_ru[i].i = (int16_t)(floor(32767.0 * sin(2 * M_PI * (double)i / N_ZC)));
|
||||
#ifdef PRACH_DEBUG
|
||||
|
||||
if (i<16)
|
||||
printf("i %d : runity %d,%d\n",i,nr_ru[i<<1],nr_ru[1+(i<<1)]);
|
||||
printf("i %d : runity %d,%d\n", i, nr_ru[i].r, nr_ru[i].i);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -59,10 +59,7 @@ uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint
|
||||
|
||||
uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r);
|
||||
|
||||
void compute_nr_prach_seq(uint8_t short_sequence,
|
||||
uint8_t num_sequences,
|
||||
uint8_t rootSequenceIndex,
|
||||
uint32_t X_u[64][839]);
|
||||
void compute_nr_prach_seq(uint8_t short_sequence, uint8_t num_sequences, uint8_t rootSequenceIndex, c16_t X_u[64][839]);
|
||||
|
||||
void nr_fill_du(uint16_t N_ZC, const uint16_t *prach_root_sequence_map);
|
||||
|
||||
|
||||
@@ -253,7 +253,9 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
uint8_t index=0;
|
||||
|
||||
int nb_re_pucch = 12*pucch_pdu->prb_size; // prb size is 1
|
||||
int32_t rp[frame_parms->nb_antennas_rx][pucch_pdu->nr_of_symbols][nb_re_pucch],*tmp_rp;
|
||||
int32_t rp[frame_parms->nb_antennas_rx][pucch_pdu->nr_of_symbols][nb_re_pucch];
|
||||
memset(rp, 0, sizeof(rp));
|
||||
int32_t *tmp_rp = NULL;
|
||||
|
||||
for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
|
||||
uint8_t l2 = l + pucch_pdu->start_symbol_index;
|
||||
@@ -1169,7 +1171,9 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
|
||||
int nb_re_pucch = 12*pucch_pdu->prb_size;
|
||||
|
||||
int16_t rp[Prx2][2][nb_re_pucch*2],*tmp_rp;
|
||||
int16_t rp[Prx2][2][nb_re_pucch*2];
|
||||
memset(rp, 0, sizeof(rp));
|
||||
int16_t *tmp_rp = NULL;
|
||||
__m64 dmrs_re,dmrs_im;
|
||||
|
||||
for (int aa=0;aa<Prx;aa++){
|
||||
|
||||
@@ -1597,13 +1597,13 @@ void NFAPI_NR_DMRS_TYPE2_average_prb(NR_DL_FRAME_PARMS *frame_parms,
|
||||
}
|
||||
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
bool is_SI,
|
||||
unsigned short p,
|
||||
unsigned char symbol,
|
||||
unsigned char nscid,
|
||||
unsigned short scrambling_id,
|
||||
unsigned short BWPStart,
|
||||
uint8_t config_type,
|
||||
uint16_t rb_offset,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
unsigned short nb_rb_pdsch,
|
||||
uint32_t pdsch_est_size,
|
||||
@@ -1629,10 +1629,6 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
#endif
|
||||
|
||||
// generate pilot for gNB port number 1000+p
|
||||
uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12;
|
||||
if (is_SI) {
|
||||
rb_offset -= BWPStart;
|
||||
}
|
||||
int8_t delta = get_delta(p, config_type);
|
||||
|
||||
// checking if re-initialization of scrambling IDs is needed
|
||||
|
||||
@@ -80,13 +80,13 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
|
||||
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
bool is_SI,
|
||||
unsigned short p,
|
||||
unsigned char symbol,
|
||||
unsigned char nscid,
|
||||
unsigned short scrambling_id,
|
||||
unsigned short BWPStart,
|
||||
uint8_t config_type,
|
||||
uint16_t rb_offset,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
unsigned short nb_rb_pdsch,
|
||||
uint32_t pdsch_est_size,
|
||||
|
||||
@@ -671,8 +671,6 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
|
||||
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
|
||||
|
||||
uint32_t frame = proc->frame_rx;
|
||||
uint32_t slot = proc->nr_slot_rx;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
|
||||
uint8_t log2_maxh, aarx;
|
||||
@@ -730,11 +728,10 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
|
||||
log2_maxh = (log2_approx(avgs) / 2) + 5; //+frame_parms->nb_antennas_rx;
|
||||
|
||||
#ifdef UE_DEBUG_TRACE
|
||||
LOG_D(PHY,"slot %d: pdcch log2_maxh = %d (%d,%d)\n",slot,log2_maxh,avgP[0],avgs);
|
||||
LOG_D(PHY, "slot %d: pdcch log2_maxh = %d (%d,%d)\n", proc->nr_slot_rx, log2_maxh, avgP[0], avgs);
|
||||
#endif
|
||||
#if T_TRACER
|
||||
T(T_UE_PHY_PDCCH_ENERGY, T_INT(0), T_INT(0), T_INT(frame%1024), T_INT(slot),
|
||||
T_INT(avgP[0]), T_INT(avgP[1]), T_INT(avgP[2]), T_INT(avgP[3]));
|
||||
T(T_UE_PHY_PDCCH_ENERGY, T_INT(0), T_INT(0), T_INT(proc->frame_rx % 1024), T_INT(proc->nr_slot_rx), T_INT(avgP[0]), T_INT(avgP[1]), T_INT(avgP[2]), T_INT(avgP[3]));
|
||||
#endif
|
||||
LOG_D(PHY,"we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh);
|
||||
LOG_D(PHY,"in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n");
|
||||
@@ -889,7 +886,8 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dci_found==1) continue;
|
||||
if (dci_found == 1)
|
||||
continue;
|
||||
int dci_length = rel15->dci_length_options[k];
|
||||
uint64_t dci_estimation[2]= {0};
|
||||
|
||||
@@ -923,8 +921,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
|
||||
if (mb > (ue->dci_thres+30)) {
|
||||
LOG_W(PHY,"DCI false positive. Dropping DCI index %d. Mismatched bits: %d/%d. Current DCI threshold: %d\n",j,mb,L*108,ue->dci_thres);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dci_ind->SFN = proc->frame_rx;
|
||||
dci_ind->slot = proc->nr_slot_rx;
|
||||
dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti;
|
||||
|
||||
@@ -515,15 +515,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
stop_meas(&ue->generic_stat_bis[slot]);
|
||||
}
|
||||
if (cpumeas(CPUMEAS_GETSTATE))
|
||||
LOG_D(PHY,
|
||||
"[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",
|
||||
frame,
|
||||
nr_slot_rx,
|
||||
slot,
|
||||
symbol,
|
||||
*log2_maxh,
|
||||
proc->channel_level,
|
||||
ue->generic_stat_bis[slot].p_time / (cpuf * 1000.0));
|
||||
LOG_D(PHY,
|
||||
"[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d Channel Comp %5.2f \n",
|
||||
frame,
|
||||
nr_slot_rx,
|
||||
slot,
|
||||
symbol,
|
||||
*log2_maxh,
|
||||
ue->generic_stat_bis[slot].p_time / (cpuf * 1000.0));
|
||||
|
||||
start_meas(&ue->generic_stat_bis[slot]);
|
||||
|
||||
|
||||
@@ -208,8 +208,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
int32_t sync_pos, sync_pos_frame; // k_ssb, N_ssb_crb, sync_pos2,
|
||||
int32_t metric_tdd_ncp=0;
|
||||
uint8_t phase_tdd_ncp;
|
||||
double im, re;
|
||||
int is;
|
||||
int frame_id;
|
||||
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
int ret=-1;
|
||||
@@ -244,14 +243,13 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
|
||||
// initial sync performed on two successive frames, if pbch passes on first frame, no need to process second frame
|
||||
// only one frame is used for symulation tools
|
||||
for(is=0; is<n_frames;is++) {
|
||||
for (frame_id = 0; frame_id < n_frames; frame_id++) {
|
||||
/* process pss search on received buffer */
|
||||
sync_pos = pss_synchro_nr(ue, frame_id, NO_RATE_CHANGE);
|
||||
if (sync_pos < fp->nb_prefix_samples)
|
||||
continue;
|
||||
|
||||
/* process pss search on received buffer */
|
||||
sync_pos = pss_synchro_nr(ue, is, NO_RATE_CHANGE);
|
||||
if (sync_pos < fp->nb_prefix_samples)
|
||||
continue;
|
||||
|
||||
ue->ssb_offset = sync_pos - fp->nb_prefix_samples;
|
||||
ue->ssb_offset = sync_pos - fp->nb_prefix_samples;
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY, "[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos, ue->common_vars.nid2);
|
||||
@@ -269,23 +267,17 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
// In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1
|
||||
// and we do not know yet in which slot it goes.
|
||||
|
||||
// start for offset correction
|
||||
int start = is*fp->samples_per_frame;
|
||||
|
||||
// loop over samples
|
||||
int end = start + fp->samples_per_frame;
|
||||
|
||||
for(int n=start; n<end; n++){
|
||||
for (int n = frame_id * fp->samples_per_frame; n < (frame_id + 1) * fp->samples_per_frame; n++) {
|
||||
for (int ar=0; ar<fp->nb_antennas_rx; ar++) {
|
||||
re = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n]);
|
||||
im = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n+1]);
|
||||
((short *)ue->common_vars.rxdata[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle)));
|
||||
((short *)ue->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle)));
|
||||
const double re = ue->common_vars.rxdata[ar][n].r;
|
||||
const double im = ue->common_vars.rxdata[ar][n].i;
|
||||
ue->common_vars.rxdata[ar][n].r = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle)));
|
||||
ue->common_vars.rxdata[ar][n].i = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* slop_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */
|
||||
/* slot_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */
|
||||
/* for NR this is not the case but slot_fep is still used for computing FFT of samples */
|
||||
/* in order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */
|
||||
/* symbol number are from beginning of SS/PBCH blocks as below: */
|
||||
@@ -295,21 +287,15 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
/* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */
|
||||
|
||||
for (int i = 0; i < NR_N_SYMBOLS_SSB; i++)
|
||||
nr_slot_fep_init_sync(ue,
|
||||
proc,
|
||||
i,
|
||||
is * fp->samples_per_frame + ue->ssb_offset,
|
||||
false,
|
||||
rxdataF,
|
||||
link_type_dl);
|
||||
nr_slot_fep_init_sync(ue, proc, i, frame_id * fp->samples_per_frame + ue->ssb_offset, false, rxdataF, link_type_dl);
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY,"Calling sss detection (normal CP)\n");
|
||||
#endif
|
||||
|
||||
int freq_offset_sss = 0;
|
||||
ret = rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss, rxdataF);
|
||||
|
||||
bool ret_sss = rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss, rxdataF);
|
||||
ret = !ret_sss;
|
||||
// digital compensation of FFO for SSB symbols
|
||||
if (ue->UE_fo_compensation){
|
||||
double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time
|
||||
@@ -317,19 +303,12 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
|
||||
// In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1
|
||||
// and we do not know yet in which slot it goes.
|
||||
|
||||
// start for offset correction
|
||||
int start = is*fp->samples_per_frame;
|
||||
|
||||
// loop over samples
|
||||
int end = start + fp->samples_per_frame;
|
||||
|
||||
for(int n=start; n<end; n++){
|
||||
for (int n = frame_id * fp->samples_per_frame; n < (frame_id + 1) * fp->samples_per_frame; n++) {
|
||||
for (int ar=0; ar<fp->nb_antennas_rx; ar++) {
|
||||
re = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n]);
|
||||
im = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n+1]);
|
||||
((short *)ue->common_vars.rxdata[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle)));
|
||||
((short *)ue->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle)));
|
||||
const double re = ue->common_vars.rxdata[ar][n].r;
|
||||
const double im = ue->common_vars.rxdata[ar][n].i;
|
||||
ue->common_vars.rxdata[ar][n].r = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle)));
|
||||
ue->common_vars.rxdata[ar][n].i = (short)(round(re * sin(n * off_angle) + im * cos(n * off_angle)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,7 +330,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
int n_symb_prefix0 = (ue->symbol_offset/(7*(1<<mu)))+1;
|
||||
sync_pos_frame = n_symb_prefix0*(fp->ofdm_symbol_size + fp->nb_prefix_samples0)+(ue->symbol_offset-n_symb_prefix0)*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
|
||||
// for a correct computation of frame number to sync with the one decoded at MIB we need to take into account in which of the n_frames we got sync
|
||||
ue->init_sync_frame = n_frames - 1 - is;
|
||||
ue->init_sync_frame = n_frames - 1 - frame_id;
|
||||
|
||||
// compute the scramblingID_pdcch and the gold pdcch
|
||||
ue->scramblingID_pdcch = fp->Nid_cell;
|
||||
@@ -409,7 +388,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
#endif
|
||||
}
|
||||
if (ret == 0) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = -1;
|
||||
@@ -444,13 +423,11 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
|
||||
LOG_I(PHY, "[UE %d] Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
|
||||
ue->Mod_id,
|
||||
openair0_cfg[0].rx_freq[0]+ue->common_vars.freq_offset,
|
||||
ue->common_vars.freq_offset);
|
||||
#endif
|
||||
LOG_I(PHY,
|
||||
"[UE %d] Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
|
||||
ue->Mod_id,
|
||||
openair0_cfg[0].rx_freq[0] + ue->common_vars.freq_offset,
|
||||
ue->common_vars.freq_offset);
|
||||
} else {
|
||||
#ifdef DEBUG_INITIAL_SYNC
|
||||
LOG_I(PHY,"[UE%d] Initial sync : PBCH not ok\n",ue->Mod_id);
|
||||
@@ -486,29 +463,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
LOG_I(PHY,"[UE%d] Initial sync : Estimated power: %d dB\n",ue->Mod_id,ue->measurements.rx_power_avg_dB[0] );
|
||||
#endif
|
||||
|
||||
#ifndef OAI_USRP
|
||||
#ifndef OAI_BLADERF
|
||||
#ifndef OAI_LMSSDR
|
||||
#ifndef OAI_ADRV9371_ZC706
|
||||
//phy_adjust_gain(ue,ue->measurements.rx_power_avg_dB[0],0);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
#ifndef OAI_USRP
|
||||
#ifndef OAI_BLADERF
|
||||
#ifndef OAI_LMSSDR
|
||||
#ifndef OAI_ADRV9371_ZC706
|
||||
//phy_adjust_gain(ue,dB_fixed(ue->measurements.rssi),0);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (ue->target_Nid_cell != -1) {
|
||||
@@ -533,7 +487,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
nr_slot_fep_init_sync(ue,
|
||||
proc,
|
||||
l, // the UE PHY has no notion of the symbols to be monitored in the search space
|
||||
is*fp->samples_per_frame+phy_pdcch_config->sfn*fp->samples_per_frame+ue->rx_offset,
|
||||
frame_id * fp->samples_per_frame + phy_pdcch_config->sfn * fp->samples_per_frame + ue->rx_offset,
|
||||
true,
|
||||
rxdataF,
|
||||
link_type_dl);
|
||||
@@ -560,7 +514,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
||||
nr_slot_fep_init_sync(ue,
|
||||
proc,
|
||||
m,
|
||||
is*fp->samples_per_frame+phy_pdcch_config->sfn*fp->samples_per_frame+ue->rx_offset,
|
||||
frame_id * fp->samples_per_frame + phy_pdcch_config->sfn * fp->samples_per_frame + ue->rx_offset,
|
||||
true,
|
||||
rxdataF,
|
||||
link_type_dl);
|
||||
|
||||
@@ -62,20 +62,18 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
|
||||
uint16_t rootSequenceIndex, prach_fmt_id, NCS, preamble_offset = 0;
|
||||
const uint16_t *prach_root_sequence_map;
|
||||
uint16_t preamble_shift = 0, preamble_index0, n_shift_ra, n_shift_ra_bar, d_start=INT16_MAX, numshift, N_ZC, u, offset, offset2, first_nonzero_root_idx;
|
||||
int16_t prach_tmp[(4688+4*24576)*4*2] __attribute__((aligned(32))) = {0};
|
||||
c16_t prach[(4688 + 4 * 24576) * 2] __attribute__((aligned(32))) = {0};
|
||||
int16_t prachF_tmp[(4688+4*24576)*4*2] __attribute__((aligned(32))) = {0};
|
||||
|
||||
int16_t Ncp = 0, amp, *prach, *prach2, *prachF, *Xu;
|
||||
int32_t Xu_re, Xu_im;
|
||||
int16_t Ncp = 0;
|
||||
int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k, prachStartSymbol, sample_offset_slot;
|
||||
|
||||
fd_occasion = 0;
|
||||
prach_len = 0;
|
||||
dftlen = 0;
|
||||
first_nonzero_root_idx = 0;
|
||||
prach = prach_tmp;
|
||||
amp = ue->prach_vars[gNB_id]->amp;
|
||||
prachF = prachF_tmp;
|
||||
first_nonzero_root_idx = 0;
|
||||
int16_t amp = ue->prach_vars[gNB_id]->amp;
|
||||
int16_t *prachF = prachF_tmp;
|
||||
Mod_id = ue->Mod_id;
|
||||
prach_sequence_length = nrUE_config->prach_config.prach_sequence_length;
|
||||
N_ZC = (prach_sequence_length == 0) ? 839:139;
|
||||
@@ -390,9 +388,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
Xu = (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx];
|
||||
c16_t *Xu = ue->X_u[preamble_offset - first_nonzero_root_idx];
|
||||
|
||||
#if defined (PRACH_WRITE_OUTPUT_DEBUG)
|
||||
#if defined (PRACH_WRITE_OUTPUT_DEBUG)
|
||||
LOG_M("X_u.m", "X_u", (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx], N_ZC, 1, 1);
|
||||
#endif
|
||||
|
||||
@@ -400,11 +398,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
|
||||
|
||||
if (offset2 >= N_ZC)
|
||||
offset2 -= N_ZC;
|
||||
|
||||
Xu_re = (((int32_t)Xu[offset<<1]*amp)>>15);
|
||||
Xu_im = (((int32_t)Xu[1+(offset<<1)]*amp)>>15);
|
||||
prachF[k++]= ((Xu_re*nr_ru[offset2<<1]) - (Xu_im*nr_ru[1+(offset2<<1)]))>>15;
|
||||
prachF[k++]= ((Xu_im*nr_ru[offset2<<1]) + (Xu_re*nr_ru[1+(offset2<<1)]))>>15;
|
||||
const int32_t Xu_re = (Xu[offset].r * amp) >> 15;
|
||||
const int32_t Xu_im = (Xu[offset].i * amp) >> 15;
|
||||
prachF[k++] = (Xu_re * nr_ru[offset2].r - Xu_im * nr_ru[offset2].i) >> 15;
|
||||
prachF[k++] = (Xu_im * nr_ru[offset2].r + Xu_re * nr_ru[offset2].i) >> 15;
|
||||
|
||||
if (k==dftlen) k=0;
|
||||
}
|
||||
@@ -415,78 +412,78 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
|
||||
#endif
|
||||
|
||||
// This is after cyclic prefix
|
||||
prach2 = prach+(2*Ncp); // times 2 for complex samples
|
||||
const idft_size_idx_t idft_size = get_idft(dftlen);
|
||||
idft(idft_size, prachF, prach, 1);
|
||||
memmove(prach2, prach, (dftlen<<2));
|
||||
c16_t *prach2 = prach + Ncp;
|
||||
const idft_size_idx_t idft_size = get_idft(dftlen);
|
||||
idft(idft_size, prachF, (int16_t *)prach, 1);
|
||||
memmove(prach2, prach, (dftlen << 2));
|
||||
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prach_fmt_id == 0) {
|
||||
// here we have | empty | Prach |
|
||||
memcpy(prach, prach+(dftlen<<1), (Ncp<<2));
|
||||
// here we have | Prefix | Prach |
|
||||
prach_len = dftlen+Ncp;
|
||||
} else if (prach_fmt_id == 1) {
|
||||
// here we have | empty | Prach | empty |
|
||||
memcpy(prach2+(dftlen<<1), prach2, (dftlen<<2));
|
||||
// here we have | empty | Prach | Prach |
|
||||
memcpy(prach, prach+(dftlen<<2), (Ncp<<2));
|
||||
// here we have | Prefix | Prach | Prach |
|
||||
prach_len = (dftlen*2)+Ncp;
|
||||
} else if (prach_fmt_id == 2 || prach_fmt_id == 3) {
|
||||
// here we have | empty | Prach | empty | empty | empty |
|
||||
memcpy(prach2+(dftlen<<1), prach2, (dftlen<<2));
|
||||
// here we have | empty | Prach | Prach | empty | empty |
|
||||
memcpy(prach2+(dftlen<<2), prach2, (dftlen<<3));
|
||||
// here we have | empty | Prach | Prach | Prach | Prach |
|
||||
memcpy(prach, prach+(dftlen<<3), (Ncp<<2));
|
||||
// here we have | Prefix | Prach | Prach | Prach | Prach |
|
||||
prach_len = (dftlen*4)+Ncp;
|
||||
}
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prach_fmt_id == 0) {
|
||||
// here we have | empty | Prach |
|
||||
memcpy(prach, prach + dftlen, (Ncp << 2));
|
||||
// here we have | Prefix | Prach |
|
||||
prach_len = dftlen + Ncp;
|
||||
} else if (prach_fmt_id == 1) {
|
||||
// here we have | empty | Prach | empty |
|
||||
memcpy(prach2 + dftlen, prach2, (dftlen << 2));
|
||||
// here we have | empty | Prach | Prach |
|
||||
memcpy(prach, prach + dftlen * 2, (Ncp << 2));
|
||||
// here we have | Prefix | Prach | Prach |
|
||||
prach_len = (dftlen * 2) + Ncp;
|
||||
} else if (prach_fmt_id == 2 || prach_fmt_id == 3) {
|
||||
// here we have | empty | Prach | empty | empty | empty |
|
||||
memcpy(prach2 + dftlen, prach2, (dftlen << 2));
|
||||
// here we have | empty | Prach | Prach | empty | empty |
|
||||
memcpy(prach2 + dftlen * 2, prach2, (dftlen << 3));
|
||||
// here we have | empty | Prach | Prach | Prach | Prach |
|
||||
memcpy(prach, prach + dftlen * 4, (Ncp << 2));
|
||||
// here we have | Prefix | Prach | Prach | Prach | Prach |
|
||||
prach_len = (dftlen * 4) + Ncp;
|
||||
}
|
||||
} else { // short PRACH sequence
|
||||
if (prach_fmt_id == 9) {
|
||||
// here we have | empty | Prach |
|
||||
memcpy(prach, prach+(dftlen<<1), (Ncp<<2));
|
||||
memcpy(prach, prach + dftlen, (Ncp << 2));
|
||||
// here we have | Prefix | Prach |
|
||||
prach_len = (dftlen*1)+Ncp;
|
||||
} else if (prach_fmt_id == 4 || prach_fmt_id == 7) {
|
||||
// here we have | empty | Prach | empty |
|
||||
memcpy(prach2+(dftlen<<1), prach2, (dftlen<<2));
|
||||
memcpy(prach2 + dftlen, prach2, (dftlen << 2));
|
||||
// here we have | empty | Prach | Prach |
|
||||
memcpy(prach, prach+(dftlen<<1), (Ncp<<2));
|
||||
// here we have | Prefix | Prach | Prach |
|
||||
prach_len = (dftlen*2)+Ncp;
|
||||
} else if (prach_fmt_id == 5 || prach_fmt_id == 10) { // 4xdftlen
|
||||
// here we have | empty | Prach | empty | empty | empty |
|
||||
memcpy(prach2+(dftlen<<1), prach2, (dftlen<<2));
|
||||
memcpy(prach2 + dftlen, prach2, (dftlen << 2));
|
||||
// here we have | empty | Prach | Prach | empty | empty |
|
||||
memcpy(prach2+(dftlen<<2), prach2, (dftlen<<3));
|
||||
memcpy(prach2 + dftlen * 2, prach2, (dftlen << 3));
|
||||
// here we have | empty | Prach | Prach | Prach | Prach |
|
||||
memcpy(prach, prach+(dftlen<<1), (Ncp<<2));
|
||||
memcpy(prach, prach + dftlen, (Ncp << 2));
|
||||
// here we have | Prefix | Prach | Prach | Prach | Prach |
|
||||
prach_len = (dftlen*4)+Ncp;
|
||||
} else if (prach_fmt_id == 6) { // 6xdftlen
|
||||
// here we have | empty | Prach | empty | empty | empty | empty | empty |
|
||||
memcpy(prach2+(dftlen<<1), prach2, (dftlen<<2));
|
||||
memcpy(prach2 + dftlen, prach2, (dftlen << 2));
|
||||
// here we have | empty | Prach | Prach | empty | empty | empty | empty |
|
||||
memcpy(prach2+(dftlen<<2), prach2, (dftlen<<3));
|
||||
memcpy(prach2 + dftlen * 2, prach2, (dftlen << 3));
|
||||
// here we have | empty | Prach | Prach | Prach | Prach | empty | empty |
|
||||
memcpy(prach2+(dftlen<<3), prach2, (dftlen<<3));
|
||||
memcpy(prach2 + dftlen * 4, prach2, (dftlen << 3));
|
||||
// here we have | empty | Prach | Prach | Prach | Prach | Prach | Prach |
|
||||
memcpy(prach, prach+(dftlen<<1), (Ncp<<2));
|
||||
memcpy(prach, prach + dftlen, (Ncp << 2));
|
||||
// here we have | Prefix | Prach | Prach | Prach | Prach | Prach | Prach |
|
||||
prach_len = (dftlen*6)+Ncp;
|
||||
} else if (prach_fmt_id == 8) { // 12xdftlen
|
||||
// here we have | empty | Prach | empty | empty | empty | empty | empty | empty | empty | empty | empty | empty | empty |
|
||||
memcpy(prach2+(dftlen<<1), prach2, (dftlen<<2));
|
||||
memcpy(prach2 + dftlen, prach2, (dftlen << 2));
|
||||
// here we have | empty | Prach | Prach | empty | empty | empty | empty | empty | empty | empty | empty | empty | empty |
|
||||
memcpy(prach2+(dftlen<<2), prach2, (dftlen<<3));
|
||||
memcpy(prach2 + dftlen * 2, prach2, (dftlen << 3));
|
||||
// here we have | empty | Prach | Prach | Prach | Prach | empty | empty | empty | empty | empty | empty | empty | empty |
|
||||
memcpy(prach2+(dftlen<<3), prach2, (dftlen<<3));
|
||||
memcpy(prach2 + dftlen * 4, prach2, (dftlen << 3));
|
||||
// here we have | empty | Prach | Prach | Prach | Prach | Prach | Prach | empty | empty | empty | empty | empty | empty |
|
||||
memcpy(prach2+(dftlen<<1)*6, prach2, (dftlen<<2)*6);
|
||||
memcpy(prach2 + dftlen * 6, prach2, (dftlen << 2) * 6);
|
||||
// here we have | empty | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach |
|
||||
memcpy(prach, prach+(dftlen<<1), (Ncp<<2));
|
||||
memcpy(prach, prach + dftlen, (Ncp << 2));
|
||||
// here we have | Prefix | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach |
|
||||
prach_len = (dftlen*12)+Ncp;
|
||||
}
|
||||
@@ -499,18 +496,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
|
||||
prach_len);
|
||||
#endif
|
||||
|
||||
for (i=0; i<prach_len; i++) {
|
||||
((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i] = prach[2*i];
|
||||
((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1];
|
||||
}
|
||||
for (i = 0; i < prach_len; i++)
|
||||
ue->common_vars.txData[0][prach_start + i] = prach[i];
|
||||
|
||||
//printf("----------------------\n");
|
||||
//for(int ii = prach_start; ii<2*(prach_start + prach_len); ii++){
|
||||
// printf("PRACH rx data[%d] = %d\n", ii, ue->common_vars.txdata[0][ii]);
|
||||
//}
|
||||
//printf(" \n");
|
||||
|
||||
#ifdef PRACH_WRITE_OUTPUT_DEBUG
|
||||
#ifdef PRACH_WRITE_OUTPUT_DEBUG
|
||||
LOG_M("prach_tx0.m", "prachtx0", prach+(Ncp<<1), prach_len-Ncp, 1, 1);
|
||||
LOG_M("Prach_txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]), 2*(prach_start+prach_len), 1, 1)
|
||||
#endif
|
||||
|
||||
@@ -238,20 +238,21 @@ void nr_pusch_codeword_scrambling(uint8_t *in,
|
||||
*/
|
||||
|
||||
void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
unsigned char harq_pid,
|
||||
uint32_t frame,
|
||||
uint8_t slot,
|
||||
int gNB_id,
|
||||
nr_phy_data_tx_t *phy_data);
|
||||
|
||||
const unsigned char harq_pid,
|
||||
const uint32_t frame,
|
||||
const uint8_t slot,
|
||||
const int gNB_id,
|
||||
nr_phy_data_tx_t *phy_data,
|
||||
c16_t **txdataF);
|
||||
|
||||
/** \brief This function does IFFT for PUSCH
|
||||
*/
|
||||
|
||||
uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
|
||||
uint8_t slot,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint8_t Nl);
|
||||
const uint8_t slot,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const uint8_t n_antenna_ports,
|
||||
c16_t **txdataF);
|
||||
|
||||
int8_t clean_UE_ulsch(PHY_VARS_NR_UE *UE, uint8_t gNB_id);
|
||||
|
||||
|
||||
@@ -107,12 +107,13 @@ void nr_pusch_codeword_scrambling(uint8_t *in,
|
||||
}
|
||||
|
||||
void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
unsigned char harq_pid,
|
||||
uint32_t frame,
|
||||
uint8_t slot,
|
||||
int gNB_id,
|
||||
nr_phy_data_tx_t *phy_data) {
|
||||
|
||||
const unsigned char harq_pid,
|
||||
const uint32_t frame,
|
||||
const uint8_t slot,
|
||||
const int gNB_id,
|
||||
nr_phy_data_tx_t *phy_data,
|
||||
c16_t **txdataF)
|
||||
{
|
||||
LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot);
|
||||
|
||||
int8_t Wf[2], Wt[2];
|
||||
@@ -122,14 +123,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
int sample_offsetF, N_RE_prime;
|
||||
|
||||
NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
|
||||
c16_t **txdataF = UE->common_vars.txdataF;
|
||||
|
||||
int N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
|
||||
uint16_t number_dmrs_symbols = 0;
|
||||
|
||||
NR_UE_ULSCH_t *ulsch_ue = &phy_data->ulsch;
|
||||
NR_UL_UE_HARQ_t *harq_process_ul_ue = &UE->ul_harq_processes[harq_pid];
|
||||
nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch_ue->pusch_pdu;
|
||||
const nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch_ue->pusch_pdu;
|
||||
|
||||
int start_symbol = pusch_pdu->start_symbol_index;
|
||||
uint16_t ul_dmrs_symb_pos = pusch_pdu->ul_dmrs_symb_pos;
|
||||
@@ -585,30 +585,17 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
|
||||
uint8_t slot,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint8_t n_antenna_ports)
|
||||
const uint8_t slot,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const uint8_t n_antenna_ports,
|
||||
c16_t **txdataF)
|
||||
{
|
||||
/////////////////////////IFFT///////////////////////
|
||||
///////////
|
||||
|
||||
int tx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
|
||||
|
||||
// clear the transmit data array for the current subframe
|
||||
/*for (int aa=0; aa<UE->frame_parms.nb_antennas_tx; aa++) {
|
||||
memset(&UE->common_vars.txdata[aa][tx_offset],0,UE->frame_parms.samples_per_slot*sizeof(int32_t));
|
||||
//memset(&UE->common_vars.txdataF[aa][tx_offset],0,UE->frame_parms.samples_per_slot*sizeof(int32_t));
|
||||
}*/
|
||||
|
||||
|
||||
c16_t **txdata = UE->common_vars.txdata;
|
||||
c16_t **txdataF = UE->common_vars.txdataF;
|
||||
const int tx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
|
||||
|
||||
c16_t **txdata = UE->common_vars.txData;
|
||||
for(int ap = 0; ap < n_antenna_ports; ap++) {
|
||||
apply_nr_rotation_TX(frame_parms,
|
||||
txdataF[ap],
|
||||
|
||||
@@ -49,13 +49,14 @@
|
||||
#endif
|
||||
|
||||
//#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
|
||||
//#define POLAR_CODING_DEBUG
|
||||
|
||||
void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
|
||||
void nr_generate_pucch0(const PHY_VARS_NR_UE *ue,
|
||||
c16_t **txdataF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int16_t amp,
|
||||
int nr_slot_tx,
|
||||
fapi_nr_ul_config_pucch_pdu *pucch_pdu)
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int16_t amp,
|
||||
const int nr_slot_tx,
|
||||
const fapi_nr_ul_config_pucch_pdu *pucch_pdu)
|
||||
{
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("\t [nr_generate_pucch0] start function at slot(nr_slot_tx)=%d\n",nr_slot_tx);
|
||||
@@ -168,12 +169,12 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
}
|
||||
|
||||
void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
|
||||
void nr_generate_pucch1(const PHY_VARS_NR_UE *ue,
|
||||
c16_t **txdataF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int16_t amp,
|
||||
int nr_slot_tx,
|
||||
fapi_nr_ul_config_pucch_pdu *pucch_pdu)
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int16_t amp,
|
||||
const int nr_slot_tx,
|
||||
const fapi_nr_ul_config_pucch_pdu *pucch_pdu)
|
||||
{
|
||||
uint16_t m0 = pucch_pdu->initial_cyclic_shift;
|
||||
uint64_t payload = pucch_pdu->payload;
|
||||
@@ -652,12 +653,13 @@ static void nr_uci_encoding(uint64_t payload,
|
||||
|
||||
}
|
||||
//#if 0
|
||||
void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
|
||||
void nr_generate_pucch2(const PHY_VARS_NR_UE *ue,
|
||||
c16_t **txdataF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int16_t amp,
|
||||
int nr_slot_tx,
|
||||
fapi_nr_ul_config_pucch_pdu *pucch_pdu) {
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int16_t amp,
|
||||
const int nr_slot_tx,
|
||||
const fapi_nr_ul_config_pucch_pdu *pucch_pdu)
|
||||
{
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("\t [nr_generate_pucch2] start function at slot(nr_slot_tx)=%d with payload=%lu and nr_bit=%d\n",nr_slot_tx, pucch_pdu->payload, pucch_pdu->n_bit);
|
||||
#endif
|
||||
@@ -692,7 +694,19 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
|
||||
/*
|
||||
* Implementing TS 38.211 Subclause 6.3.2.5.1 scrambling format 2
|
||||
*/
|
||||
nr_pucch2_3_4_scrambling(M_bit,rnti,pucch_pdu->data_scrambling_id,&b[0],btilde);
|
||||
nr_pucch2_3_4_scrambling(M_bit, rnti, pucch_pdu->data_scrambling_id, b, btilde);
|
||||
|
||||
#ifdef POLAR_CODING_DEBUG
|
||||
printf("bt:");
|
||||
for (int n = 0; n < M_bit; n++) {
|
||||
if (n % 4 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
printf("%u", btilde[n]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Implementing TS 38.211 Subclause 6.3.2.5.2 modulation format 2
|
||||
* btilde shall be modulated as described in subclause 5.1 using QPSK
|
||||
@@ -848,12 +862,13 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
|
||||
free(btilde);
|
||||
}
|
||||
//#if 0
|
||||
void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
|
||||
void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue,
|
||||
c16_t **txdataF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int16_t amp,
|
||||
int nr_slot_tx,
|
||||
fapi_nr_ul_config_pucch_pdu *pucch_pdu) {
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int16_t amp,
|
||||
const int nr_slot_tx,
|
||||
const fapi_nr_ul_config_pucch_pdu *pucch_pdu)
|
||||
{
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("\t [nr_generate_pucch3_4] start function at slot(nr_slot_tx)=%d with payload=%lu and nr_bit=%d\n", nr_slot_tx, pucch_pdu->payload, pucch_pdu->n_bit);
|
||||
#endif
|
||||
@@ -1317,4 +1332,3 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
|
||||
free(z_im);
|
||||
free(btilde);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,34 +44,33 @@
|
||||
#include "T.h"
|
||||
#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
|
||||
|
||||
|
||||
void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
|
||||
void nr_generate_pucch0(const PHY_VARS_NR_UE *ue,
|
||||
c16_t **txdataF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int16_t amp,
|
||||
int nr_slot_tx,
|
||||
fapi_nr_ul_config_pucch_pdu *pucch_pdu);
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int16_t amp,
|
||||
const int nr_slot_tx,
|
||||
const fapi_nr_ul_config_pucch_pdu *pucch_pdu);
|
||||
|
||||
void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
|
||||
void nr_generate_pucch1(const PHY_VARS_NR_UE *ue,
|
||||
c16_t **txdataF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int16_t amp,
|
||||
int nr_slot_tx,
|
||||
fapi_nr_ul_config_pucch_pdu *pucch_pdu);
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int16_t amp,
|
||||
const int nr_slot_tx,
|
||||
const fapi_nr_ul_config_pucch_pdu *pucch_pdu);
|
||||
|
||||
void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
|
||||
void nr_generate_pucch2(const PHY_VARS_NR_UE *ue,
|
||||
c16_t **txdataF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int16_t amp,
|
||||
int nr_slot_tx,
|
||||
fapi_nr_ul_config_pucch_pdu *pucch_pdu);
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int16_t amp,
|
||||
const int nr_slot_tx,
|
||||
const fapi_nr_ul_config_pucch_pdu *pucch_pdu);
|
||||
|
||||
void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
|
||||
void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue,
|
||||
c16_t **txdataF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int16_t amp,
|
||||
int nr_slot_tx,
|
||||
fapi_nr_ul_config_pucch_pdu *pucch_pdu);
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int16_t amp,
|
||||
const int nr_slot_tx,
|
||||
const fapi_nr_ul_config_pucch_pdu *pucch_pdu);
|
||||
|
||||
// tables for mcs values for different payloads
|
||||
static const uint8_t table1_mcs[]={0,6,3,9};
|
||||
|
||||
@@ -432,7 +432,7 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu,
|
||||
* send srs according to current configuration
|
||||
*
|
||||
*********************************************************************/
|
||||
int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc)
|
||||
int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t **txdataF)
|
||||
{
|
||||
if(!ue->srs_vars[0]->active) {
|
||||
return -1;
|
||||
@@ -471,8 +471,15 @@ int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc)
|
||||
NR_DL_FRAME_PARMS *frame_parms = &(ue->frame_parms);
|
||||
uint16_t symbol_offset = (frame_parms->symbols_per_slot - 1 - srs_config_pdu->time_start_position)*frame_parms->ofdm_symbol_size;
|
||||
|
||||
if (generate_srs_nr(srs_config_pdu, frame_parms, (int32_t **)ue->common_vars.txdataF, symbol_offset, ue->nr_srs_info,
|
||||
AMP, proc->frame_tx, proc->nr_slot_tx) == 0) {
|
||||
if (generate_srs_nr(srs_config_pdu,
|
||||
frame_parms,
|
||||
(int32_t **)txdataF,
|
||||
symbol_offset,
|
||||
ue->nr_srs_info,
|
||||
AMP,
|
||||
proc->frame_tx,
|
||||
proc->nr_slot_tx)
|
||||
== 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
|
||||
@@ -177,7 +177,7 @@ int is_srs_period_nr(SRS_Resource_t *p_SRS_Resource,
|
||||
@param current gNB_id identifier
|
||||
@returns 0 if srs is transmitted -1 otherwise */
|
||||
|
||||
int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc);
|
||||
int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t **txdataF);
|
||||
|
||||
#undef EXTERN
|
||||
#undef INIT_VARIABLES_SRS_MODULATION_NR_H
|
||||
|
||||
@@ -350,24 +350,23 @@ static int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : rx_sss_nr
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : Set Nid_cell in ue context
|
||||
*
|
||||
* DESCRIPTION : Determine element Nid1 of cell identity
|
||||
* so Nid_cell in ue context is set according to Nid1 & Nid2
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
int rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
int32_t *tot_metric,
|
||||
uint8_t *phase_max,
|
||||
int *freq_offset_sss,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
||||
*
|
||||
* NAME : rx_sss_nr
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : Set Nid_cell in ue context, return true if cell detected
|
||||
*
|
||||
* DESCRIPTION : Determine element Nid1 of cell identity
|
||||
* so Nid_cell in ue context is set according to Nid1 & Nid2
|
||||
*
|
||||
*********************************************************************/
|
||||
bool rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
int32_t *tot_metric,
|
||||
uint8_t *phase_max,
|
||||
int *freq_offset_sss,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
||||
{
|
||||
uint8_t i;
|
||||
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR];
|
||||
@@ -506,13 +505,13 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
//#endif
|
||||
|
||||
if (Nid1==N_ID_1_NUMBER)
|
||||
return -1;
|
||||
|
||||
return false;
|
||||
|
||||
int re = 0;
|
||||
int im = 0;
|
||||
if (Nid1 == N_ID_1_NUMBER) {
|
||||
LOG_I(PHY,"Failed to detect SSS after PSS\n");
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
d = (int16_t *)&d_sss[Nid2][Nid1];
|
||||
for(i = 0; i<LENGTH_SSS_NR; i++) {
|
||||
@@ -523,8 +522,16 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue,
|
||||
*freq_offset_sss = (int)(ffo_sss*frame_parms->subcarrier_spacing);
|
||||
|
||||
double ffo_pss = ((double)ue->common_vars.freq_offset)/frame_parms->subcarrier_spacing;
|
||||
LOG_I(NR_PHY, "ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz)\n",
|
||||
ffo_pss, (int)(ffo_pss*frame_parms->subcarrier_spacing), ffo_sss, *freq_offset_sss, ffo_pss+ffo_sss, (int)((ffo_pss+ffo_sss)*frame_parms->subcarrier_spacing));
|
||||
LOG_W(NR_PHY,
|
||||
"ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz), nid1: %d, nid2: %d\n",
|
||||
ffo_pss,
|
||||
(int)(ffo_pss * frame_parms->subcarrier_spacing),
|
||||
ffo_sss,
|
||||
*freq_offset_sss,
|
||||
ffo_pss + ffo_sss,
|
||||
(int)((ffo_pss + ffo_sss) * frame_parms->subcarrier_spacing),
|
||||
Nid1,
|
||||
Nid2);
|
||||
|
||||
return(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -83,11 +83,7 @@ void multadd_real_vector_complex_scalar(const int16_t *x, const int16_t *alpha,
|
||||
}
|
||||
}
|
||||
|
||||
void rotate_cpx_vector(c16_t *x,
|
||||
c16_t *alpha,
|
||||
c16_t *y,
|
||||
uint32_t N,
|
||||
uint16_t output_shift)
|
||||
void rotate_cpx_vector(const c16_t *const x, const c16_t *const alpha, c16_t *y, uint32_t N, uint16_t output_shift)
|
||||
{
|
||||
// multiply a complex vector with a complex value (alpha)
|
||||
// stores result in y
|
||||
@@ -98,12 +94,41 @@ void rotate_cpx_vector(c16_t *x,
|
||||
// output is 32 bytes aligned, but not the input
|
||||
|
||||
const c16_t for_re={alpha->r, -alpha->i};
|
||||
__m256i const alpha_for_real = simde_mm256_set1_epi32(*(uint32_t*)&for_re);
|
||||
const __m256i alpha_for_real = simde_mm256_set1_epi32(*(uint32_t *)&for_re);
|
||||
const c16_t for_im={alpha->i, alpha->r};
|
||||
__m256i const alpha_for_im= simde_mm256_set1_epi32(*(uint32_t*)&for_im);
|
||||
__m256i const perm_mask =
|
||||
simde_mm256_set_epi8(31,30,23,22,29,28,21,20,27,26,19,18,25,24,17,16,
|
||||
15,14,7,6,13,12,5,4,11,10,3,2,9,8,1,0);
|
||||
const __m256i alpha_for_im = simde_mm256_set1_epi32(*(uint32_t *)&for_im);
|
||||
const __m256i perm_mask = simde_mm256_set_epi8(31,
|
||||
30,
|
||||
23,
|
||||
22,
|
||||
29,
|
||||
28,
|
||||
21,
|
||||
20,
|
||||
27,
|
||||
26,
|
||||
19,
|
||||
18,
|
||||
25,
|
||||
24,
|
||||
17,
|
||||
16,
|
||||
15,
|
||||
14,
|
||||
7,
|
||||
6,
|
||||
13,
|
||||
12,
|
||||
5,
|
||||
4,
|
||||
11,
|
||||
10,
|
||||
3,
|
||||
2,
|
||||
9,
|
||||
8,
|
||||
1,
|
||||
0);
|
||||
__m256i* xd= (__m256i*)x;
|
||||
const __m256i *end=xd+N/8;
|
||||
for( __m256i* yd = (__m256i *)y; xd<end ; yd++, xd++) {
|
||||
|
||||
@@ -455,6 +455,9 @@ static void timeSignal (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy
|
||||
|
||||
static void timeResponse (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
|
||||
const int len = p->gNB->frame_parms.ofdm_symbol_size;
|
||||
if (!len)
|
||||
// gnb not yet initialized, many race conditions in the scope
|
||||
return;
|
||||
#ifdef WEBSRVSCOPE
|
||||
websrv_scopedata_msg_t *msg = NULL;
|
||||
websrv_nf_getdata(graph->graph, 0, &msg);
|
||||
|
||||
@@ -34,8 +34,10 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <atomic>
|
||||
#ifndef _Atomic
|
||||
#define _Atomic(X) std::atomic< X >
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <openair1/PHY/defs_gNB.h>
|
||||
#include <openair1/PHY/defs_nr_UE.h>
|
||||
|
||||
@@ -741,12 +741,7 @@ This function performs componentwise multiplication of a vector with a complex s
|
||||
|
||||
The function implemented is : \f$\mathbf{y} = \alpha\mathbf{x}\f$
|
||||
*/
|
||||
void rotate_cpx_vector(c16_t *x,
|
||||
c16_t *alpha,
|
||||
c16_t *y,
|
||||
uint32_t N,
|
||||
uint16_t output_shift);
|
||||
|
||||
void rotate_cpx_vector(const c16_t *const x, const c16_t *const alpha, c16_t *y, uint32_t N, uint16_t output_shift);
|
||||
|
||||
//cadd_sv.c
|
||||
|
||||
|
||||
@@ -679,7 +679,7 @@ typedef struct PHY_VARS_gNB_s {
|
||||
uint32_t ****nr_gold_prs;
|
||||
|
||||
/// PRACH root sequence
|
||||
uint32_t X_u[64][839];
|
||||
c16_t X_u[64][839];
|
||||
|
||||
/// OFDM symbol offset divisor for UL
|
||||
uint32_t ofdm_offset_divisor;
|
||||
|
||||
@@ -221,7 +221,7 @@ typedef struct {
|
||||
/// For IFFT_FPGA this points to the same memory as PHY_vars->tx_vars[a].TX_DMA_BUFFER.
|
||||
/// - first index: tx antenna [0..nb_antennas_tx[
|
||||
/// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES[
|
||||
c16_t **txdata;
|
||||
c16_t **txData;
|
||||
/// \brief Holds the transmit data in the frequency domain.
|
||||
/// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER.
|
||||
/// - first index: tx antenna [0..nb_antennas_tx[
|
||||
@@ -485,8 +485,8 @@ typedef struct {
|
||||
|
||||
// PRS sequence per gNB, per resource
|
||||
uint32_t *****nr_gold_prs;
|
||||
|
||||
uint32_t X_u[64][839];
|
||||
|
||||
c16_t X_u[64][839];
|
||||
|
||||
// flag to activate PRB based averaging of channel estimates
|
||||
// when off, defaults to frequency domain interpolation
|
||||
@@ -664,6 +664,24 @@ typedef struct {
|
||||
int tx_wait_for_dlsch[NR_MAX_SLOTS_PER_FRAME];
|
||||
} PHY_VARS_NR_UE;
|
||||
|
||||
typedef struct {
|
||||
openair0_timestamp timestamp_tx;
|
||||
int gNB_id;
|
||||
/// NR slot index within frame_tx [0 .. slots_per_frame - 1] to act upon for transmission
|
||||
int nr_slot_tx;
|
||||
int rx_slot_type;
|
||||
/// NR slot index within frame_rx [0 .. slots_per_frame - 1] to act upon for transmission
|
||||
int nr_slot_rx;
|
||||
int tx_slot_type;
|
||||
//#endif
|
||||
/// frame to act upon for transmission
|
||||
int frame_tx;
|
||||
/// frame to act upon for reception
|
||||
int frame_rx;
|
||||
int frame_number_4lsb;
|
||||
int decoded_frame_rx;
|
||||
} UE_nr_rxtx_proc_t;
|
||||
|
||||
typedef struct nr_phy_data_tx_s {
|
||||
NR_UE_ULSCH_t ulsch;
|
||||
NR_UE_PUCCH pucch_vars;
|
||||
|
||||
@@ -131,10 +131,10 @@ typedef struct {
|
||||
|
||||
typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS;
|
||||
|
||||
typedef uint32_t (*get_samples_per_slot_t)(int slot, NR_DL_FRAME_PARMS* fp);
|
||||
typedef uint32_t (*get_slot_from_timestamp_t)(openair0_timestamp timestamp_rx, NR_DL_FRAME_PARMS* fp);
|
||||
typedef uint32_t (*get_samples_per_slot_t)(int slot, const NR_DL_FRAME_PARMS *fp);
|
||||
typedef uint32_t (*get_slot_from_timestamp_t)(openair0_timestamp timestamp_rx, const NR_DL_FRAME_PARMS *fp);
|
||||
|
||||
typedef uint32_t (*get_samples_slot_timestamp_t)(int slot, NR_DL_FRAME_PARMS* fp, uint8_t sl_ahead);
|
||||
typedef uint32_t (*get_samples_slot_timestamp_t)(int slot, const NR_DL_FRAME_PARMS *fp, uint8_t sl_ahead);
|
||||
|
||||
struct NR_DL_FRAME_PARMS {
|
||||
/// frequency range
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
#ifndef __thread_NR_UE__
|
||||
#define __thread_NR_UE__
|
||||
#include <pthread.h>
|
||||
#include <radio/COMMON/common_lib.h>
|
||||
/// Context data structure for RX/TX portion of subframe processing
|
||||
typedef struct {
|
||||
/// Component Carrier index
|
||||
uint8_t CC_id;
|
||||
/// timestamp transmitted to HW
|
||||
openair0_timestamp timestamp_tx;
|
||||
//#ifdef UE_NR_PHY_DEMO
|
||||
int gNB_id;
|
||||
/// NR slot index within frame_tx [0 .. slots_per_frame - 1] to act upon for transmission
|
||||
int nr_slot_tx;
|
||||
int rx_slot_type;
|
||||
/// NR slot index within frame_rx [0 .. slots_per_frame - 1] to act upon for transmission
|
||||
int nr_slot_rx;
|
||||
int tx_slot_type;
|
||||
//#endif
|
||||
/// frame to act upon for transmission
|
||||
int frame_tx;
|
||||
/// frame to act upon for reception
|
||||
int frame_rx;
|
||||
int decoded_frame_rx;
|
||||
/// internal This variable is protected by ref mutex_fep_slot1.
|
||||
//int instance_cnt_slot0_dl_processing;
|
||||
int instance_cnt_slot1_dl_processing;
|
||||
/// pthread descriptor fep_slot1 thread
|
||||
//pthread_t pthread_slot0_dl_processing;
|
||||
pthread_t pthread_slot1_dl_processing;
|
||||
/// pthread attributes for fep_slot1 processing thread
|
||||
/// condition variable for UE fep_slot1 thread;
|
||||
//pthread_cond_t cond_slot0_dl_processing;
|
||||
pthread_cond_t cond_slot1_dl_processing;
|
||||
/// mutex for UE synch thread
|
||||
//pthread_mutex_t mutex_slot0_dl_processing;
|
||||
pthread_mutex_t mutex_slot1_dl_processing;
|
||||
//int instance_cnt_slot0_dl_processing;
|
||||
int instance_cnt_dlsch_td;
|
||||
/// pthread descriptor fep_slot1 thread
|
||||
//pthread_t pthread_slot0_dl_processing;
|
||||
pthread_t pthread_dlsch_td;
|
||||
/// pthread attributes for fep_slot1 processing thread
|
||||
/// condition variable for UE fep_slot1 thread;
|
||||
//pthread_cond_t cond_slot0_dl_processing;
|
||||
pthread_cond_t cond_dlsch_td;
|
||||
/// mutex for UE synch thread
|
||||
uint8_t chan_est_pilot0_slot1_available;
|
||||
uint8_t chan_est_slot1_available;
|
||||
uint8_t llr_slot1_available;
|
||||
uint8_t dci_slot0_available;
|
||||
uint8_t first_symbol_available;
|
||||
uint8_t decoder_thread_available;
|
||||
uint8_t decoder_main_available;
|
||||
uint8_t decoder_switch;
|
||||
int num_seg;
|
||||
uint8_t channel_level;
|
||||
int eNB_id;
|
||||
int harq_pid;
|
||||
int llr8_flag;
|
||||
/// scheduling parameters for fep_slot1 thread
|
||||
struct sched_param sched_param_fep_slot1;
|
||||
|
||||
int sub_frame_start;
|
||||
int sub_frame_step;
|
||||
uint8_t decoder_thread_available1;
|
||||
int dci_err_cnt;
|
||||
} UE_nr_rxtx_proc_t;
|
||||
|
||||
#endif
|
||||
@@ -200,6 +200,7 @@ void common_signal_procedures_fembms (PHY_VARS_eNB *eNB,int frame, int subframe)
|
||||
eNB->pbch_configured=0;
|
||||
}
|
||||
|
||||
#if T_TRACER
|
||||
if (T_ACTIVE(T_ENB_PHY_MIB)) {
|
||||
/* MIB is stored in reverse in pbch_pdu, reverse it for properly logging */
|
||||
uint8_t mib[3];
|
||||
@@ -209,6 +210,7 @@ void common_signal_procedures_fembms (PHY_VARS_eNB *eNB,int frame, int subframe)
|
||||
T(T_ENB_PHY_MIB, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe),
|
||||
T_BUFFER(mib, 3));
|
||||
}
|
||||
#endif
|
||||
generate_pbch_fembms (&eNB->pbch, txdataF, AMP, fp, pbch_pdu, (frame & 15)/4);
|
||||
} //else if ((subframe == 1) && (fp->frame_type == TDD)) {
|
||||
//generate_pss (txdataF, AMP, fp, 2, 2);
|
||||
@@ -276,6 +278,7 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) {
|
||||
eNB->pbch_configured=0;
|
||||
}
|
||||
|
||||
#if T_TRACER
|
||||
if (T_ACTIVE(T_ENB_PHY_MIB)) {
|
||||
/* MIB is stored in reverse in pbch_pdu, reverse it for properly logging */
|
||||
uint8_t mib[3];
|
||||
@@ -285,6 +288,7 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) {
|
||||
T(T_ENB_PHY_MIB, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe),
|
||||
T_BUFFER(mib, 3));
|
||||
}
|
||||
#endif
|
||||
generate_pbch (&eNB->pbch, txdataF, AMP, fp, pbch_pdu, frame & 3);
|
||||
} else if ((subframe == 1) && (fp->frame_type == TDD)) {
|
||||
generate_pss (txdataF, AMP, fp, 2, 2);
|
||||
|
||||
@@ -99,6 +99,7 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_
|
||||
cfg,
|
||||
fp);
|
||||
|
||||
#if T_TRACER
|
||||
if (T_ACTIVE(T_GNB_PHY_MIB)) {
|
||||
unsigned char bch[3];
|
||||
bch[0] = ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff;
|
||||
@@ -106,6 +107,7 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_
|
||||
bch[2] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff;
|
||||
T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Beam_id is currently used only for FR2
|
||||
if (fp->freq_range==nr_FR2){
|
||||
@@ -135,14 +137,14 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
||||
PHY_VARS_gNB *gNB = msgTx->gNB;
|
||||
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
int offset = gNB->CC_id, slot_prs;
|
||||
int slot_prs = 0;
|
||||
int txdataF_offset = slot*fp->samples_per_slot_wCP;
|
||||
prs_config_t *prs_config = NULL;
|
||||
|
||||
if ((cfg->cell_config.frame_duplex_type.value == TDD) &&
|
||||
(nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,1);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX + gNB->CC_id, 1);
|
||||
|
||||
// clear the transmit data array and beam index for the current slot
|
||||
for (aa=0; aa<cfg->carrier_config.num_tx_ant.value; aa++) {
|
||||
@@ -235,7 +237,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
||||
T_INT(aa), T_BUFFER(&gNB->common_vars.txdataF[aa][txdataF_offset], fp->samples_per_slot_wCP*sizeof(int32_t)));
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,0);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX + gNB->CC_id, 0);
|
||||
}
|
||||
|
||||
static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
|
||||
|
||||
@@ -96,7 +96,7 @@ typedef struct {
|
||||
@param proc Pointer to RXn-TXnp4 proc information
|
||||
@param eNB_id Local id of eNB on which to act
|
||||
*/
|
||||
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data);
|
||||
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data);
|
||||
|
||||
void send_slot_ind(notifiedFIFO_t *nf, int slot);
|
||||
|
||||
@@ -117,7 +117,7 @@ void processSlotTX(void *arg);
|
||||
@param
|
||||
@param
|
||||
*/
|
||||
void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc);
|
||||
void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc);
|
||||
|
||||
int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
|
||||
|
||||
|
||||
@@ -301,13 +301,12 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void configure_dlsch(NR_UE_DLSCH_t *dlsch0,
|
||||
NR_DL_UE_HARQ_t *harq_list,
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
|
||||
module_id_t module_id,
|
||||
int rnti) {
|
||||
|
||||
static void configure_dlsch(NR_UE_DLSCH_t *dlsch0,
|
||||
NR_DL_UE_HARQ_t *harq_list,
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
|
||||
module_id_t module_id,
|
||||
int rnti)
|
||||
{
|
||||
const uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
|
||||
dlsch0->active = true;
|
||||
dlsch0->rnti = rnti;
|
||||
@@ -331,7 +330,6 @@ void configure_dlsch(NR_UE_DLSCH_t *dlsch0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void configure_ta_command(PHY_VARS_NR_UE *ue, fapi_nr_ta_command_pdu *ta_command_pdu)
|
||||
{
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@
|
||||
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
|
||||
|
||||
//#define DEBUG_PHY_PROC
|
||||
#define NR_PDCCH_SCHED
|
||||
//#define NR_PDCCH_SCHED_DEBUG
|
||||
//#define NR_PUCCH_SCHED
|
||||
//#define NR_PUCCH_SCHED_DEBUG
|
||||
@@ -75,10 +74,6 @@ fifo_dump_emos_UE emos_dump_UE;
|
||||
#include "intertask_interface.h"
|
||||
#include "T.h"
|
||||
|
||||
#if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
|
||||
extern uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
#endif
|
||||
|
||||
unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162};
|
||||
|
||||
void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
|
||||
@@ -264,43 +259,43 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx)
|
||||
}
|
||||
}
|
||||
|
||||
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
nr_phy_data_tx_t *phy_data) {
|
||||
|
||||
int slot_tx = proc->nr_slot_tx;
|
||||
int frame_tx = proc->frame_tx;
|
||||
int gNB_id = proc->gNB_id;
|
||||
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data)
|
||||
{
|
||||
const int slot_tx = proc->nr_slot_tx;
|
||||
const int frame_tx = proc->frame_tx;
|
||||
const int gNB_id = proc->gNB_id;
|
||||
|
||||
AssertFatal(ue->CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
|
||||
|
||||
const int samplesF_per_slot = NR_SYMBOLS_PER_SLOT * ue->frame_parms.ofdm_symbol_size;
|
||||
c16_t txdataF_buf[ue->frame_parms.nb_antennas_tx * samplesF_per_slot] __attribute__((aligned(32)));
|
||||
memset(txdataF_buf, 0, sizeof(txdataF_buf));
|
||||
c16_t *txdataF[ue->frame_parms.nb_antennas_tx]; /* workaround to be compatible with current txdataF usage in all tx procedures. */
|
||||
for(int i=0; i< ue->frame_parms.nb_antennas_tx; ++i)
|
||||
memset(ue->common_vars.txdataF[i], 0, sizeof(int)*14*ue->frame_parms.ofdm_symbol_size);
|
||||
txdataF[i] = &txdataF_buf[i * samplesF_per_slot];
|
||||
|
||||
LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
|
||||
|
||||
start_meas(&ue->phy_proc_tx);
|
||||
|
||||
for (uint8_t harq_pid = 0; harq_pid < NR_MAX_ULSCH_HARQ_PROCESSES; harq_pid++) {
|
||||
if (ue->ul_harq_processes[harq_pid].status == ACTIVE)
|
||||
nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, gNB_id, phy_data);
|
||||
if (ue->ul_harq_processes[harq_pid].status == ACTIVE) {
|
||||
nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, gNB_id, phy_data, (c16_t **)&txdataF);
|
||||
}
|
||||
}
|
||||
|
||||
ue_srs_procedures_nr(ue, proc);
|
||||
ue_srs_procedures_nr(ue, proc, (c16_t **)&txdataF);
|
||||
|
||||
pucch_procedures_ue_nr(ue, proc, phy_data);
|
||||
pucch_procedures_ue_nr(ue, proc, phy_data, (c16_t **)&txdataF);
|
||||
|
||||
LOG_D(PHY, "Sending Uplink data \n");
|
||||
nr_ue_pusch_common_procedures(ue,
|
||||
proc->nr_slot_tx,
|
||||
&ue->frame_parms,
|
||||
ue->frame_parms.nb_antennas_tx);
|
||||
nr_ue_pusch_common_procedures(ue, proc->nr_slot_tx, &ue->frame_parms, ue->frame_parms.nb_antennas_tx, (c16_t **)txdataF);
|
||||
|
||||
nr_ue_prach_procedures(ue, proc);
|
||||
|
||||
LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", proc->frame_tx, proc->nr_slot_tx);
|
||||
LOG_D(PHY, "****** end TX-Chain for AbsSubframe %d.%d ******\n", proc->frame_tx, proc->nr_slot_tx);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
|
||||
stop_meas(&ue->phy_proc_tx);
|
||||
@@ -314,7 +309,6 @@ void nr_ue_measurement_procedures(uint16_t l,
|
||||
int32_t dl_ch_estimates[][pdsch_est_size]) {
|
||||
|
||||
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
|
||||
int frame_rx = proc->frame_rx;
|
||||
int nr_slot_rx = proc->nr_slot_rx;
|
||||
int gNB_id = proc->gNB_id;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN);
|
||||
@@ -331,14 +325,18 @@ void nr_ue_measurement_procedures(uint16_t l,
|
||||
|
||||
#if T_TRACER
|
||||
if(nr_slot_rx == 0)
|
||||
T(T_UE_PHY_MEAS, T_INT(gNB_id), T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_slot_rx),
|
||||
T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)),
|
||||
T_INT((int)ue->measurements.rx_rssi_dBm[0]),
|
||||
T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)),
|
||||
T_INT((int)ue->measurements.rx_power_avg_dB[0]),
|
||||
T_INT((int)ue->measurements.n0_power_avg_dB),
|
||||
T_INT((int)ue->measurements.wideband_cqi_avg[0]),
|
||||
T_INT((int)ue->common_vars.freq_offset));
|
||||
T(T_UE_PHY_MEAS,
|
||||
T_INT(gNB_id),
|
||||
T_INT(ue->Mod_id),
|
||||
T_INT(proc->frame_rx % 1024),
|
||||
T_INT(nr_slot_rx),
|
||||
T_INT((int)(10 * log10(ue->measurements.rsrp[0]) - ue->rx_total_gain_dB)),
|
||||
T_INT((int)ue->measurements.rx_rssi_dBm[0]),
|
||||
T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)),
|
||||
T_INT((int)ue->measurements.rx_power_avg_dB[0]),
|
||||
T_INT((int)ue->measurements.n0_power_avg_dB),
|
||||
T_INT((int)ue->measurements.wideband_cqi_avg[0]),
|
||||
T_INT((int)ue->common_vars.freq_offset));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -402,37 +400,12 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue,
|
||||
#endif
|
||||
|
||||
} else {
|
||||
LOG_E(PHY,"[UE %d] frame %d, nr_slot_rx %d, Error decoding PBCH!\n",
|
||||
ue->Mod_id,frame_rx, nr_slot_rx);
|
||||
/*FILE *fd;
|
||||
if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) {
|
||||
fwrite((void *)&ue->common_vars.rxdata[0][0],
|
||||
sizeof(int32_t),
|
||||
ue->frame_parms.samples_per_frame,
|
||||
fd);
|
||||
LOG_I(PHY,"Dummping Frame ... bye bye \n");
|
||||
fclose(fd);
|
||||
exit(0);
|
||||
}*/
|
||||
|
||||
/*
|
||||
write_output("rxsig0.m","rxs0", ue->common_vars.rxdata[0],ue->frame_parms.samples_per_subframe,1,1);
|
||||
|
||||
|
||||
write_output("H00.m","h00",&(ue->common_vars.dl_ch_estimates[0][0][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1);
|
||||
write_output("H10.m","h10",&(ue->common_vars.dl_ch_estimates[0][2][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1);
|
||||
|
||||
write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],8*ue->frame_parms.ofdm_symbol_size,1,1);
|
||||
exit(-1);
|
||||
*/
|
||||
|
||||
LOG_E(PHY, "[UE %d] frame %d, nr_slot_rx %d, Error decoding PBCH!\n", ue->Mod_id, frame_rx, nr_slot_rx);
|
||||
}
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb)
|
||||
{
|
||||
|
||||
@@ -450,8 +423,6 @@ unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef NR_PDCCH_SCHED
|
||||
|
||||
int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
int32_t pdcch_est_size,
|
||||
@@ -478,7 +449,7 @@ int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
|
||||
nr_rx_pdcch(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, pdcch_e_rx, rel15, rxdataF);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT);
|
||||
|
||||
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_IN);
|
||||
|
||||
@@ -492,9 +463,8 @@ int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
|
||||
#ifdef NR_PDCCH_SCHED_DEBUG
|
||||
LOG_I(PHY,"<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%u\n",dci_cnt);
|
||||
#endif
|
||||
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT);
|
||||
//LOG_D(PHY,"[UE %d][PUSCH] Frame %d nr_slot_rx %d PHICH RX\n",ue->Mod_id,frame_rx,nr_slot_rx);
|
||||
|
||||
for (int i=0; i<dci_cnt; i++) {
|
||||
LOG_D(PHY,"[UE %d] AbsSubFrame %d.%d: DCI %i of %d total DCIs found --> rnti %x : format %d\n",
|
||||
@@ -512,13 +482,11 @@ int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
|
||||
// send to mac
|
||||
ue->if_inst->dl_indication(&dl_indication);
|
||||
|
||||
|
||||
stop_meas(&ue->dlsch_rx_pdcch_stats);
|
||||
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
|
||||
return(dci_cnt);
|
||||
}
|
||||
#endif // NR_PDCCH_SCHED
|
||||
|
||||
int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
@@ -544,10 +512,9 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
uint16_t pdsch_nb_rb = dlsch0->dlsch_config.number_rbs;
|
||||
uint16_t s0 = dlsch0->dlsch_config.start_symbol;
|
||||
uint16_t s1 = dlsch0->dlsch_config.number_symbols;
|
||||
bool is_SI = dlsch0->rnti_type == _SI_RNTI_;
|
||||
|
||||
LOG_D(PHY,"[UE %d] nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x, Nl %d\n",
|
||||
ue->Mod_id,nr_slot_rx,harq_pid,dlsch0_harq->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->dlsch_config.dlDmrsSymbPos, dlsch0->Nl);
|
||||
LOG_D(PHY,"[UE %d] nr_slot_rx %d, harq_pid %d (%d), BWP start %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x, Nl %d\n",
|
||||
ue->Mod_id,nr_slot_rx,harq_pid,dlsch0_harq->status,BWPStart,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->dlsch_config.dlDmrsSymbPos, dlsch0->Nl);
|
||||
|
||||
const uint32_t pdsch_est_size = ((ue->frame_parms.symbols_per_slot * ue->frame_parms.ofdm_symbol_size + 15) / 16) * 16;
|
||||
__attribute__((aligned(32))) int32_t pdsch_dl_ch_estimates[ue->frame_parms.nb_antennas_rx * dlsch0->Nl][pdsch_est_size];
|
||||
@@ -569,13 +536,13 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
LOG_D(PHY,"PDSCH Channel estimation gNB id %d, PDSCH antenna port %d, slot %d, symbol %d\n",0,aatx,nr_slot_rx,m);
|
||||
nr_pdsch_channel_estimation(ue,
|
||||
proc,
|
||||
is_SI,
|
||||
get_dmrs_port(aatx,dlsch0->dlsch_config.dmrs_ports),
|
||||
m,
|
||||
dlsch0->dlsch_config.nscid,
|
||||
dlsch0->dlsch_config.dlDmrsScramblingId,
|
||||
BWPStart,
|
||||
dlsch0->dlsch_config.dmrsConfigType,
|
||||
dlsch0->dlsch_config.rb_offset,
|
||||
ue->frame_parms.first_carrier_offset+(BWPStart + pdsch_start_rb)*12,
|
||||
pdsch_nb_rb,
|
||||
pdsch_est_size,
|
||||
@@ -658,10 +625,12 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
|
||||
stop_meas(&ue->dlsch_llr_stats_parallelization[slot]);
|
||||
if (cpumeas(CPUMEAS_GETSTATE))
|
||||
LOG_D(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",frame_rx,nr_slot_rx,m,ue->dlsch_llr_stats_parallelization[slot].p_time/(cpuf*1000.0));
|
||||
if(first_symbol_flag) {
|
||||
proc->first_symbol_available = 1;
|
||||
}
|
||||
LOG_D(PHY,
|
||||
"[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",
|
||||
frame_rx,
|
||||
nr_slot_rx,
|
||||
m,
|
||||
ue->dlsch_llr_stats_parallelization[slot].p_time / (cpuf * 1000.0));
|
||||
} // CRNTI active
|
||||
stop_meas(&ue->rx_pdsch_stats);
|
||||
}
|
||||
@@ -1004,8 +973,6 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue,
|
||||
LOG_I(NR_PHY,"============================================\n");
|
||||
}
|
||||
|
||||
#ifdef NR_PDCCH_SCHED
|
||||
|
||||
LOG_D(PHY," ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_IN);
|
||||
|
||||
@@ -1058,7 +1025,6 @@ void pdsch_processing(PHY_VARS_NR_UE *ue,
|
||||
int gNB_id = proc->gNB_id;
|
||||
|
||||
NR_UE_DLSCH_t *dlsch = &phy_data->dlsch[0];
|
||||
#endif //NR_PDCCH_SCHED
|
||||
start_meas(&ue->generic_stat);
|
||||
// do procedures for C-RNTI
|
||||
int ret_pdsch = 0;
|
||||
@@ -1199,7 +1165,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue,
|
||||
|
||||
stop_meas(&ue->generic_stat);
|
||||
if (cpumeas(CPUMEAS_GETSTATE))
|
||||
LOG_D(PHY,"after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0));
|
||||
LOG_D(PHY, "after ldpc decode until end of Rx %5.2f \n", ue->generic_stat.p_time / (cpuf * 1000.0));
|
||||
|
||||
#ifdef EMOS
|
||||
phy_procedures_emos_UE_RX(ue,slot,gNB_id);
|
||||
@@ -1219,8 +1185,8 @@ void pdsch_processing(PHY_VARS_NR_UE *ue,
|
||||
|
||||
// todo:
|
||||
// - power control as per 38.213 ch 7.4
|
||||
void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc) {
|
||||
|
||||
void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc)
|
||||
{
|
||||
int gNB_id = proc->gNB_id;
|
||||
int frame_tx = proc->frame_tx, nr_slot_tx = proc->nr_slot_tx, prach_power; // tx_amp
|
||||
uint8_t mod_id = ue->Mod_id;
|
||||
@@ -1228,7 +1194,6 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);
|
||||
|
||||
if (ue->prach_vars[gNB_id]->active) {
|
||||
|
||||
fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu;
|
||||
ue->tx_power_dBm[nr_slot_tx] = prach_pdu->prach_tx_power;
|
||||
|
||||
|
||||
@@ -198,18 +198,14 @@ void nr_generate_pucch3_4(int32_t **txdataF,
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
nr_phy_data_tx_t *phy_data) {
|
||||
|
||||
int nr_slot_tx = proc->nr_slot_tx;
|
||||
fapi_nr_ul_config_pucch_pdu *pucch_pdu;
|
||||
void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txdataF)
|
||||
{
|
||||
const int nr_slot_tx = proc->nr_slot_tx;
|
||||
NR_UE_PUCCH *pucch_vars = &phy_data->pucch_vars;
|
||||
|
||||
for (int i=0; i<2; i++) {
|
||||
if(pucch_vars->active[i]) {
|
||||
|
||||
pucch_pdu = &pucch_vars->pucch_pdu[i];
|
||||
const fapi_nr_ul_config_pucch_pdu *pucch_pdu = &pucch_vars->pucch_pdu[i];
|
||||
uint16_t nb_of_prbs = pucch_pdu->prb_size;
|
||||
/* Generate PUCCH signal according to its format and parameters */
|
||||
|
||||
@@ -238,37 +234,17 @@ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue,
|
||||
|
||||
switch(pucch_pdu->format_type) {
|
||||
case 0:
|
||||
nr_generate_pucch0(ue,
|
||||
ue->common_vars.txdataF,
|
||||
&ue->frame_parms,
|
||||
tx_amp,
|
||||
nr_slot_tx,
|
||||
pucch_pdu);
|
||||
nr_generate_pucch0(ue, txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu);
|
||||
break;
|
||||
case 1:
|
||||
nr_generate_pucch1(ue,
|
||||
ue->common_vars.txdataF,
|
||||
&ue->frame_parms,
|
||||
tx_amp,
|
||||
nr_slot_tx,
|
||||
pucch_pdu);
|
||||
nr_generate_pucch1(ue, txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu);
|
||||
break;
|
||||
case 2:
|
||||
nr_generate_pucch2(ue,
|
||||
ue->common_vars.txdataF,
|
||||
&ue->frame_parms,
|
||||
tx_amp,
|
||||
nr_slot_tx,
|
||||
pucch_pdu);
|
||||
nr_generate_pucch2(ue, txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu);
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
nr_generate_pucch3_4(ue,
|
||||
ue->common_vars.txdataF,
|
||||
&ue->frame_parms,
|
||||
tx_amp,
|
||||
nr_slot_tx,
|
||||
pucch_pdu);
|
||||
nr_generate_pucch3_4(ue, txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -276,8 +252,6 @@ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int dummy_csi_status = 0;
|
||||
uint32_t dummy_csi_payload = 0;
|
||||
|
||||
|
||||
@@ -58,10 +58,7 @@
|
||||
|
||||
/*************** FUNCTIONS ****************************************/
|
||||
|
||||
void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
nr_phy_data_tx_t *phy_data);
|
||||
|
||||
void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txdataF);
|
||||
|
||||
void set_csi_nr(int csi_status, uint32_t csi_payload);
|
||||
|
||||
|
||||
@@ -2731,6 +2731,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,
|
||||
CBA_RNTI,
|
||||
eNB_id,
|
||||
0)==0)) {
|
||||
#if T_TRACER
|
||||
int harq_pid = subframe2harq_pid(&ue->frame_parms,
|
||||
pdcch_alloc2ul_frame(&ue->frame_parms,proc->frame_rx,proc->subframe_rx),
|
||||
pdcch_alloc2ul_subframe(&ue->frame_parms,proc->subframe_rx));
|
||||
@@ -2749,6 +2750,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,
|
||||
pdcch_alloc2ul_subframe(&ue->frame_parms,proc->subframe_rx));
|
||||
LOG_D(PHY,"[UE %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else if( (dci_alloc_rx[i].rnti == ue->ulsch[eNB_id]->cba_rnti[0]) &&
|
||||
(dci_alloc_rx[i].format == format0)) {
|
||||
|
||||
@@ -902,7 +902,6 @@ int main(int argc, char **argv) {
|
||||
// moreover you need to init itti with the following line
|
||||
// however itti will catch all signals, so ctrl-c won't work anymore
|
||||
// alternatively you can disable ITTI completely in CMakeLists.txt
|
||||
T_stdout = 1;
|
||||
|
||||
if (common_flag == 0) {
|
||||
switch (N_RB_DL) {
|
||||
|
||||
@@ -398,7 +398,6 @@ int main(int argc, char **argv) {
|
||||
AssertFatal(load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) != NULL, "Cannot load configuration module, exiting\n");
|
||||
logInit();
|
||||
set_glog(OAILOG_INFO);
|
||||
T_stdout = 1;
|
||||
// enable these lines if you need debug info
|
||||
// however itti will catch all signals, so ctrl-c won't work anymore
|
||||
// alternatively you can disable ITTI completely in CMakeLists.txt
|
||||
|
||||
@@ -342,7 +342,6 @@ int main(int argc, char **argv)
|
||||
|
||||
logInit();
|
||||
set_glog(loglvl);
|
||||
T_stdout = 1;
|
||||
|
||||
if (snr1set == 0)
|
||||
snr1 = snr0 + 10;
|
||||
@@ -412,7 +411,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
//configure UE
|
||||
UE = malloc(sizeof(PHY_VARS_NR_UE));
|
||||
UE = calloc(1, sizeof(*UE));
|
||||
memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS));
|
||||
|
||||
//phy_init_nr_top(frame_parms);
|
||||
|
||||
@@ -610,7 +610,6 @@ int main(int argc, char **argv)
|
||||
|
||||
logInit();
|
||||
set_glog(loglvl);
|
||||
T_stdout = 1;
|
||||
/* initialize the sin table */
|
||||
InitSinLUT();
|
||||
|
||||
@@ -708,13 +707,11 @@ int main(int argc, char **argv)
|
||||
N_RB_DL,g_mcsTableIdx,0);
|
||||
|
||||
// TODO do a UECAP for phy-sim
|
||||
const gNB_RrcConfigurationReq conf = {
|
||||
.pdsch_AntennaPorts = pdsch_AntennaPorts,
|
||||
.minRXTXTIME = 6,
|
||||
.do_CSIRS = 0,
|
||||
.do_SRS = 0,
|
||||
.force_256qam_off = false
|
||||
};
|
||||
const gNB_RrcConfigurationReq conf = {.pdsch_AntennaPorts = pdsch_AntennaPorts,
|
||||
.minRXTXTIME = 6,
|
||||
.do_CSIRS = 0,
|
||||
.do_SRS = 0,
|
||||
.force_256qam_off = false};
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, scd, UE_Capability_nr, 0, 1, &conf, 0);
|
||||
|
||||
/* RRC parameter validation for secondaryCellGroup */
|
||||
|
||||
@@ -478,7 +478,6 @@ int main(int argc, char **argv)
|
||||
|
||||
logInit();
|
||||
set_glog(loglvl);
|
||||
T_stdout = 1;
|
||||
|
||||
if (snr1set==0)
|
||||
snr1 = snr0+10;
|
||||
|
||||
@@ -411,7 +411,6 @@ int main(int argc, char **argv){
|
||||
// Configure log
|
||||
logInit();
|
||||
set_glog(loglvl);
|
||||
T_stdout = 1;
|
||||
SET_LOG_DEBUG(PRACH);
|
||||
|
||||
// Configure gNB and RU
|
||||
@@ -597,7 +596,7 @@ int main(int argc, char **argv){
|
||||
|
||||
ue_prach_pdu = &UE->prach_vars[0]->prach_pdu;
|
||||
ue_prach_config = &UE->nrUE_config.prach_config;
|
||||
txdata = UE->common_vars.txdata;
|
||||
txdata = UE->common_vars.txData;
|
||||
|
||||
UE->prach_vars[0]->amp = AMP;
|
||||
ue_prach_pdu->root_seq_id = rootSequenceIndex;
|
||||
|
||||
@@ -123,7 +123,7 @@ int main(int argc, char **argv)
|
||||
int16_t amp=0x7FFF;
|
||||
int nr_slot_tx=0;
|
||||
int nr_frame_tx=0;
|
||||
uint64_t actual_payload=0,payload_received;
|
||||
uint64_t actual_payload = 0, payload_received = 0;
|
||||
bool random_payload = true;
|
||||
int nr_bit=1; // maximum value possible is 2
|
||||
uint8_t m0=0;// higher layer paramater initial cyclic shift
|
||||
|
||||
@@ -377,7 +377,6 @@ int main(int argc, char **argv)
|
||||
|
||||
logInit();
|
||||
set_glog(loglvl);
|
||||
T_stdout = 1;
|
||||
|
||||
if (snr1set == 0)
|
||||
snr1 = snr0 + 10;
|
||||
@@ -428,7 +427,7 @@ int main(int argc, char **argv)
|
||||
phy_init_nr_gNB(gNB);
|
||||
|
||||
//configure UE
|
||||
UE = malloc(sizeof(PHY_VARS_NR_UE));
|
||||
UE = calloc(1, sizeof(*UE));
|
||||
memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS));
|
||||
|
||||
UE->frame_parms.nb_antennas_tx = n_tx;
|
||||
|
||||
@@ -561,7 +561,6 @@ int main(int argc, char **argv)
|
||||
|
||||
logInit();
|
||||
set_glog(loglvl);
|
||||
T_stdout = 1;
|
||||
|
||||
get_softmodem_params()->phy_test = 1;
|
||||
get_softmodem_params()->do_ra = 0;
|
||||
@@ -634,14 +633,12 @@ int main(int argc, char **argv)
|
||||
N_RB_UL,0,mcs_table);
|
||||
|
||||
// TODO do a UECAP for phy-sim
|
||||
const gNB_RrcConfigurationReq conf = {
|
||||
.pdsch_AntennaPorts = { .N1 = 1, .N2 = 1, .XP = 1 },
|
||||
.pusch_AntennaPorts = n_rx,
|
||||
.minRXTXTIME = 0,
|
||||
.do_CSIRS = 0,
|
||||
.do_SRS = 0,
|
||||
.force_256qam_off = false
|
||||
};
|
||||
const gNB_RrcConfigurationReq conf = {.pdsch_AntennaPorts = {.N1 = 1, .N2 = 1, .XP = 1},
|
||||
.pusch_AntennaPorts = n_rx,
|
||||
.minRXTXTIME = 0,
|
||||
.do_CSIRS = 0,
|
||||
.do_SRS = 0,
|
||||
.force_256qam_off = false};
|
||||
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, scd, UE_Capability_nr, 0, 1, &conf, 0);
|
||||
|
||||
@@ -1186,14 +1183,14 @@ int main(int argc, char **argv)
|
||||
phy_procedures_nrUE_TX(UE, &UE_proc, &phy_data);
|
||||
|
||||
if (n_trials == 1) {
|
||||
LOG_M("txsig0.m", "txs0", &UE->common_vars.txdata[0][slot_offset], slot_length, 1, 1);
|
||||
LOG_M("txsig0.m", "txs0", &UE->common_vars.txData[0][slot_offset], slot_length, 1, 1);
|
||||
LOG_M("txsig0F.m", "txs0F", UE->common_vars.txdataF[0], frame_parms->ofdm_symbol_size * 14, 1, 1);
|
||||
if (precod_nbr_layers > 1) {
|
||||
LOG_M("txsig1.m", "txs1", &UE->common_vars.txdata[1][slot_offset], slot_length, 1, 1);
|
||||
LOG_M("txsig1.m", "txs1", &UE->common_vars.txData[1][slot_offset], slot_length, 1, 1);
|
||||
LOG_M("txsig1F.m", "txs1F", UE->common_vars.txdataF[1], frame_parms->ofdm_symbol_size * 14, 1, 1);
|
||||
if (precod_nbr_layers == 4) {
|
||||
LOG_M("txsig2.m", "txs2", &UE->common_vars.txdata[2][slot_offset], slot_length, 1, 1);
|
||||
LOG_M("txsig3.m", "txs3", &UE->common_vars.txdata[3][slot_offset], slot_length, 1, 1);
|
||||
LOG_M("txsig2.m", "txs2", &UE->common_vars.txData[2][slot_offset], slot_length, 1, 1);
|
||||
LOG_M("txsig3.m", "txs3", &UE->common_vars.txData[3][slot_offset], slot_length, 1, 1);
|
||||
LOG_M("txsig2F.m", "txs2F", UE->common_vars.txdataF[2], frame_parms->ofdm_symbol_size * 14, 1, 1);
|
||||
LOG_M("txsig3F.m", "txs3F", UE->common_vars.txdataF[3], frame_parms->ofdm_symbol_size * 14, 1, 1);
|
||||
}
|
||||
@@ -1204,8 +1201,10 @@ int main(int argc, char **argv)
|
||||
tx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
|
||||
txlev_sum = 0;
|
||||
for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) {
|
||||
atxlev[aa] = signal_energy((int32_t *)&UE->common_vars.txdata[aa][tx_offset + 5 * frame_parms->ofdm_symbol_size + 4 * frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
|
||||
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
|
||||
atxlev[aa] = signal_energy(
|
||||
(int32_t *)&UE->common_vars.txData[aa][tx_offset + 5 * frame_parms->ofdm_symbol_size
|
||||
+ 4 * frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
|
||||
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
|
||||
|
||||
txlev_sum += atxlev[aa];
|
||||
|
||||
@@ -1226,8 +1225,8 @@ int main(int argc, char **argv)
|
||||
|
||||
for (i = 0; i < slot_length; i++) {
|
||||
for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) {
|
||||
s_re[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i << 1)]);
|
||||
s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i << 1) + 1]);
|
||||
s_re[aa][i] = (double)UE->common_vars.txData[aa][slot_offset + i].r;
|
||||
s_im[aa][i] = (double)UE->common_vars.txData[aa][slot_offset + i].i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ void fill_channel_desc(channel_desc_t *chan_desc,
|
||||
LOG_D(OCM,"[CHANNEL] Doing delays ...\n");
|
||||
|
||||
if (delays==NULL) {
|
||||
chan_desc->delays = (double *) malloc(nb_taps*sizeof(double));
|
||||
chan_desc->delays = calloc(nb_taps, sizeof(double));
|
||||
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_DELAY ;
|
||||
delta_tau = Td/nb_taps;
|
||||
|
||||
@@ -131,22 +131,22 @@ void fill_channel_desc(channel_desc_t *chan_desc,
|
||||
chan_desc->first_run = 1;
|
||||
chan_desc->ip = 0.0;
|
||||
chan_desc->max_Doppler = max_Doppler;
|
||||
chan_desc->ch = (struct complexd **) malloc(nb_tx*nb_rx*sizeof(struct complexd *));
|
||||
chan_desc->chF = (struct complexd **) malloc(nb_tx*nb_rx*sizeof(struct complexd *));
|
||||
chan_desc->a = (struct complexd **) malloc(nb_taps*sizeof(struct complexd *));
|
||||
chan_desc->ch = calloc(nb_tx*nb_rx, sizeof(struct complexd *));
|
||||
chan_desc->chF = calloc(nb_tx*nb_rx, sizeof(struct complexd *));
|
||||
chan_desc->a = calloc(nb_taps, sizeof(struct complexd *));
|
||||
LOG_D(OCM,"[CHANNEL] Filling ch \n");
|
||||
|
||||
for (i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->ch[i] = (struct complexd *) malloc(channel_length * sizeof(struct complexd));
|
||||
chan_desc->ch[i] = calloc(channel_length, sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(275 * 12 * sizeof(struct complexd)); // allocate for up to 275 RBs, 12 symbols per RB
|
||||
chan_desc->chF[i] = calloc(275 * 12, sizeof(struct complexd)); // allocate for up to 275 RBs, 12 symbols per RB
|
||||
|
||||
LOG_D(OCM,"[CHANNEL] Filling a (nb_taps %d)\n",nb_taps);
|
||||
|
||||
for (i = 0; i<nb_taps; i++) {
|
||||
LOG_D(OCM,"tap %d (%p,%zu)\n",i,&chan_desc->a[i],nb_tx*nb_rx * sizeof(struct complexd));
|
||||
chan_desc->a[i] = (struct complexd *) malloc(nb_tx*nb_rx * sizeof(struct complexd));
|
||||
chan_desc->a[i] = calloc(nb_tx*nb_rx, sizeof(struct complexd));
|
||||
}
|
||||
|
||||
LOG_D(OCM,"[CHANNEL] Doing R_sqrt ...\n");
|
||||
@@ -367,7 +367,7 @@ void tdlModel(int tdl_paths, double *tdl_delays, double *tdl_amps_dB, double DS
|
||||
2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
|
||||
printf("TDL : %f Ms/s, nb_taps %d, Td %e, channel_length %d\n",chan_desc->sampling_rate,tdl_paths,chan_desc->Td,chan_desc->channel_length);
|
||||
double sum_amps = 0;
|
||||
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
|
||||
chan_desc->amps = calloc(chan_desc->nb_taps, sizeof(double));
|
||||
|
||||
for (int i = 0; i<chan_desc->nb_taps; i++) {
|
||||
chan_desc->amps[i] = pow(10,.1*tdl_amps_dB[i]);
|
||||
@@ -382,19 +382,19 @@ void tdlModel(int tdl_paths, double *tdl_delays, double *tdl_amps_dB, double DS
|
||||
chan_desc->delays = tdl_delays;
|
||||
chan_desc->aoa = 0;
|
||||
chan_desc->random_aoa = 0;
|
||||
chan_desc->ch = (struct complexd **) malloc(nb_tx*nb_rx*sizeof(struct complexd *));
|
||||
chan_desc->chF = (struct complexd **) malloc(nb_tx*nb_rx*sizeof(struct complexd *));
|
||||
chan_desc->a = (struct complexd **) malloc(chan_desc->nb_taps*sizeof(struct complexd *));
|
||||
chan_desc->ch = calloc(nb_tx*nb_rx, sizeof(struct complexd *));
|
||||
chan_desc->chF = calloc(nb_tx*nb_rx, sizeof(struct complexd *));
|
||||
chan_desc->a = calloc(chan_desc->nb_taps, sizeof(struct complexd *));
|
||||
chan_desc->ricean_factor = 1.0;
|
||||
|
||||
for (int i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->ch[i] = (struct complexd *) malloc(chan_desc->channel_length * sizeof(struct complexd));
|
||||
chan_desc->ch[i] = calloc(chan_desc->channel_length, sizeof(struct complexd));
|
||||
|
||||
for (int i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->chF[i] = (struct complexd *) malloc((2+(275*12)) * sizeof(struct complexd));
|
||||
chan_desc->chF[i] = calloc(2+(275*12), sizeof(struct complexd));
|
||||
|
||||
for (int i = 0; i<chan_desc->nb_taps; i++)
|
||||
chan_desc->a[i] = (struct complexd *) malloc(nb_tx*nb_rx * sizeof(struct complexd));
|
||||
chan_desc->a[i] = calloc(nb_tx*nb_rx, sizeof(struct complexd));
|
||||
|
||||
int matrix_size = nb_tx*nb_rx;
|
||||
double *correlation_matrix[matrix_size];
|
||||
@@ -446,9 +446,9 @@ void tdlModel(int tdl_paths, double *tdl_delays, double *tdl_amps_dB, double DS
|
||||
}
|
||||
}
|
||||
|
||||
chan_desc->R_sqrt = (struct complexd **) malloc(matrix_size*sizeof(struct complexd **));
|
||||
chan_desc->R_sqrt = calloc(matrix_size, sizeof(*chan_desc->R_sqrt));
|
||||
for (int row = 0; row < matrix_size; row++) {
|
||||
chan_desc->R_sqrt[row] = (struct complexd *) calloc(1, matrix_size*sizeof(struct complexd));
|
||||
chan_desc->R_sqrt[row] = calloc(matrix_size, sizeof(**chan_desc->R_sqrt));
|
||||
if (correlation_matrix[row] == NULL) {
|
||||
// TS 38.104 - Table G.2.3.1.2-4: MIMO correlation matrices for low correlation
|
||||
chan_desc->R_sqrt[row][row].r = 1.0;
|
||||
@@ -637,7 +637,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
chan_desc->Td = 4.625;
|
||||
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
|
||||
sum_amps = 0;
|
||||
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
|
||||
chan_desc->amps = calloc(chan_desc->nb_taps, sizeof(double));
|
||||
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
|
||||
|
||||
for (i = 0; i<chan_desc->nb_taps; i++) {
|
||||
@@ -657,15 +657,15 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
chan_desc->a = (struct complexd **) malloc(chan_desc->nb_taps*sizeof(struct complexd *));
|
||||
|
||||
for (i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->ch[i] = (struct complexd *) malloc(chan_desc->channel_length * sizeof(struct complexd));
|
||||
chan_desc->ch[i] = calloc(chan_desc->channel_length, sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(1200 * sizeof(struct complexd));
|
||||
chan_desc->chF[i] = calloc(1200, sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<chan_desc->nb_taps; i++)
|
||||
chan_desc->a[i] = (struct complexd *) malloc(nb_tx*nb_rx * sizeof(struct complexd));
|
||||
chan_desc->a[i] = calloc(nb_tx*nb_rx, sizeof(struct complexd));
|
||||
|
||||
chan_desc->R_sqrt = (struct complexd **) malloc(6*sizeof(struct complexd **));
|
||||
chan_desc->R_sqrt = calloc(6, sizeof(struct complexd **));
|
||||
|
||||
if (nb_tx==2 && nb_rx==2) {
|
||||
for (i = 0; i<6; i++)
|
||||
@@ -680,7 +680,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
|
||||
|
||||
for (i = 0; i<6; i++) {
|
||||
chan_desc->R_sqrt[i] = (struct complexd *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complexd));
|
||||
chan_desc->R_sqrt[i] = calloc(nb_tx*nb_rx*nb_tx*nb_rx, sizeof(struct complexd));
|
||||
|
||||
for (j = 0; j<nb_tx*nb_rx*nb_tx*nb_rx; j+=(nb_tx*nb_rx+1)) {
|
||||
chan_desc->R_sqrt[i][j].r = 1.0;
|
||||
|
||||
@@ -6,3 +6,4 @@ add_subdirectory(F1AP)
|
||||
add_subdirectory(M2AP)
|
||||
add_subdirectory(X2AP)
|
||||
add_subdirectory(RRC)
|
||||
add_subdirectory(XNAP)
|
||||
|
||||
@@ -467,6 +467,7 @@ typedef struct rrc_subframe_process_s {
|
||||
typedef struct nrrrc_slot_process_s {
|
||||
int frame;
|
||||
int slot;
|
||||
int gnb_id;
|
||||
} NRRrcSlotProcess;
|
||||
|
||||
// eNB: RLC -> RRC messages
|
||||
|
||||
@@ -701,7 +701,7 @@ void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs)
|
||||
void nr_rrc_mac_config_req_mib(module_id_t module_id,
|
||||
int cc_idP,
|
||||
NR_MIB_t *mib,
|
||||
bool sched_sib1)
|
||||
int sched_sib)
|
||||
{
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
AssertFatal(mib, "MIB should not be NULL\n");
|
||||
@@ -709,16 +709,21 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id,
|
||||
mac->mib = mib; // update by every reception
|
||||
mac->phy_config.Mod_id = module_id;
|
||||
mac->phy_config.CC_id = cc_idP;
|
||||
mac->get_sib1 = sched_sib1;
|
||||
if (sched_sib == 1)
|
||||
mac->get_sib1 = true;
|
||||
else if (sched_sib == 2)
|
||||
mac->get_otherSI = true;
|
||||
}
|
||||
|
||||
void nr_rrc_mac_config_req_sib1(module_id_t module_id,
|
||||
int cc_idP,
|
||||
struct NR_SI_SchedulingInfo *si_SchedulingInfo,
|
||||
NR_ServingCellConfigCommonSIB_t *scc)
|
||||
{
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
AssertFatal(scc, "SIB1 SCC should not be NULL\n");
|
||||
mac->scc_SIB = scc;
|
||||
mac->si_SchedulingInfo = si_SchedulingInfo;
|
||||
mac->nr_band = *scc->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR;
|
||||
config_common_ue_sa(mac, module_id, cc_idP);
|
||||
configure_current_BWP(mac, scc, NULL);
|
||||
|
||||
@@ -382,6 +382,43 @@ typedef struct NR_UL_TIME_ALIGNMENT {
|
||||
int slot;
|
||||
} NR_UL_TIME_ALIGNMENT_t;
|
||||
|
||||
// The PRACH Config period is a series of selected slots in one or multiple frames
|
||||
typedef struct prach_conf_period {
|
||||
prach_occasion_slot_t prach_occasion_slot_map[MAX_NB_FRAME_IN_PRACH_CONF_PERIOD][MAX_NB_SLOT_IN_FRAME];
|
||||
uint16_t nb_of_prach_occasion; // Total number of PRACH occasions in the PRACH Config period
|
||||
uint8_t nb_of_frame; // Size of the PRACH Config period in number of 10ms frames
|
||||
uint8_t nb_of_slot; // Nb of slots in each frame
|
||||
} prach_conf_period_t;
|
||||
|
||||
// The association period is a series of PRACH Config periods
|
||||
typedef struct prach_association_period {
|
||||
prach_conf_period_t *prach_conf_period_list[MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PERIOD];
|
||||
uint8_t nb_of_prach_conf_period; // Nb of PRACH configuration periods within the association period
|
||||
uint8_t nb_of_frame; // Total number of frames included in the association period
|
||||
} prach_association_period_t;
|
||||
|
||||
// The association pattern is a series of Association periods
|
||||
typedef struct prach_association_pattern {
|
||||
prach_association_period_t prach_association_period_list[MAX_NB_ASSOCIATION_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD];
|
||||
prach_conf_period_t prach_conf_period_list[MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD];
|
||||
uint8_t nb_of_assoc_period; // Nb of association periods within the association pattern
|
||||
uint8_t nb_of_prach_conf_period_in_max_period; // Nb of PRACH configuration periods within the maximum association pattern period (according to the size of the configured PRACH
|
||||
uint8_t nb_of_frame; // Total number of frames included in the association pattern period (after mapping the SSBs and determining the real association pattern length)
|
||||
} prach_association_pattern_t;
|
||||
|
||||
// SSB details
|
||||
typedef struct ssb_info {
|
||||
bool transmitted; // True if the SSB index is transmitted according to the SSB positions map configuration
|
||||
prach_occasion_info_t *mapped_ro[MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN]; // List of mapped RACH Occasions to this SSB index
|
||||
uint32_t nb_mapped_ro; // Total number of mapped ROs to this SSB index
|
||||
} ssb_info_t;
|
||||
|
||||
// List of all the possible SSBs and their details
|
||||
typedef struct ssb_list_info {
|
||||
ssb_info_t tx_ssb[MAX_NB_SSB];
|
||||
uint8_t nb_tx_ssb;
|
||||
} ssb_list_info_t;
|
||||
|
||||
/*!\brief Top level UE MAC structure */
|
||||
typedef struct {
|
||||
NR_UE_L2_STATE_t state;
|
||||
@@ -394,6 +431,7 @@ typedef struct {
|
||||
//// MAC config
|
||||
int first_sync_frame;
|
||||
bool get_sib1;
|
||||
bool get_otherSI;
|
||||
NR_DRX_Config_t *drx_Config;
|
||||
NR_SchedulingRequestConfig_t *schedulingRequestConfig;
|
||||
NR_BSR_Config_t *bsr_Config;
|
||||
@@ -401,6 +439,9 @@ typedef struct {
|
||||
NR_PHR_Config_t *phr_Config;
|
||||
NR_RNTI_Value_t *cs_RNTI;
|
||||
NR_MIB_t *mib;
|
||||
struct NR_SI_SchedulingInfo *si_SchedulingInfo;
|
||||
int si_window_start;
|
||||
ssb_list_info_t ssb_list;
|
||||
|
||||
NR_UE_DL_BWP_t current_DL_BWP;
|
||||
NR_UE_UL_BWP_t current_UL_BWP;
|
||||
@@ -484,43 +525,5 @@ typedef struct {
|
||||
|
||||
} NR_UE_MAC_INST_t;
|
||||
|
||||
|
||||
// The PRACH Config period is a series of selected slots in one or multiple frames
|
||||
typedef struct prach_conf_period {
|
||||
prach_occasion_slot_t prach_occasion_slot_map[MAX_NB_FRAME_IN_PRACH_CONF_PERIOD][MAX_NB_SLOT_IN_FRAME];
|
||||
uint16_t nb_of_prach_occasion; // Total number of PRACH occasions in the PRACH Config period
|
||||
uint8_t nb_of_frame; // Size of the PRACH Config period in number of 10ms frames
|
||||
uint8_t nb_of_slot; // Nb of slots in each frame
|
||||
} prach_conf_period_t;
|
||||
|
||||
// The association period is a series of PRACH Config periods
|
||||
typedef struct prach_association_period {
|
||||
prach_conf_period_t *prach_conf_period_list[MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PERIOD];
|
||||
uint8_t nb_of_prach_conf_period; // Nb of PRACH configuration periods within the association period
|
||||
uint8_t nb_of_frame; // Total number of frames included in the association period
|
||||
} prach_association_period_t;
|
||||
|
||||
// The association pattern is a series of Association periods
|
||||
typedef struct prach_association_pattern {
|
||||
prach_association_period_t prach_association_period_list[MAX_NB_ASSOCIATION_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD];
|
||||
prach_conf_period_t prach_conf_period_list[MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD];
|
||||
uint8_t nb_of_assoc_period; // Nb of association periods within the association pattern
|
||||
uint8_t nb_of_prach_conf_period_in_max_period; // Nb of PRACH configuration periods within the maximum association pattern period (according to the size of the configured PRACH
|
||||
uint8_t nb_of_frame; // Total number of frames included in the association pattern period (after mapping the SSBs and determining the real association pattern length)
|
||||
} prach_association_pattern_t;
|
||||
|
||||
// SSB details
|
||||
typedef struct ssb_info {
|
||||
bool transmitted; // True if the SSB index is transmitted according to the SSB positions map configuration
|
||||
prach_occasion_info_t *mapped_ro[MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN]; // List of mapped RACH Occasions to this SSB index
|
||||
uint32_t nb_mapped_ro; // Total number of mapped ROs to this SSB index
|
||||
} ssb_info_t;
|
||||
|
||||
// List of all the possible SSBs and their details
|
||||
typedef struct ssb_list_info {
|
||||
ssb_info_t tx_ssb[MAX_NB_SSB];
|
||||
uint8_t nb_tx_ssb;
|
||||
} ssb_list_info_t;
|
||||
|
||||
/*@}*/
|
||||
#endif /*__LAYER2_MAC_DEFS_H__ */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user