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:
Robert Schmidt
2023-07-16 13:48:23 +00:00
127 changed files with 13256 additions and 1638 deletions
+46 -64
View File
@@ -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
View File
@@ -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;;
+3
View File
@@ -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 \
+53
View File
@@ -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)
{
+1
View File
@@ -8,3 +8,4 @@ if(ENABLE_WEBSRV)
add_subdirectory(websrv)
endif()
add_subdirectory(T)
+1 -1
View File
@@ -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)
+50
View File
@@ -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()
+20
View File
@@ -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)
+90
View File
@@ -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).
+3
View File
@@ -0,0 +1,3 @@
![enb_trace](./enb_trace.png)
[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

+95
View File
@@ -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.
+210
View File
@@ -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 {
+57
View File
@@ -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.
+34
View File
@@ -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.
+39
View File
@@ -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
```
+21
View File
@@ -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
```
+158
View File
@@ -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:
![wireshark window with dissected MAC PDUs](wireshark.png)
## 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

+1 -1
View File
@@ -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
+9 -4
View File
@@ -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;
+73
View File
@@ -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)
+44 -8
View File
@@ -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);
}
+1
View File
@@ -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);
+2 -2
View File
@@ -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 ..)
+10
View File
@@ -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})
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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 ..)
+1 -1
View File
@@ -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;
}
-3
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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];
}
}
+10 -4
View File
@@ -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);
+38 -43
View File
@@ -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]);
+3 -3
View File
@@ -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;
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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,
+4 -4
View File
@@ -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",
+6 -6
View File
@@ -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 */
+1 -1
View File
@@ -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"};
+7 -10
View File
@@ -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);
+6 -2
View File
@@ -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,
+5 -8
View File
@@ -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]);
+30 -76
View File
@@ -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);
+55 -66
View File
@@ -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);
+14 -27
View File
@@ -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],
+36 -22
View File
@@ -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);
}
+20 -21
View File
@@ -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
+31 -24
View File
@@ -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;
}
+35 -10
View File
@@ -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++) {
+3
View File
@@ -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);
+2
View File
@@ -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>
+1 -6
View File
@@ -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
+1 -1
View File
@@ -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;
+21 -3
View File
@@ -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;
+3 -3
View File
@@ -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
-70
View File
@@ -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
+4
View File
@@ -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);
+5 -3
View File
@@ -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)
+2 -2
View File
@@ -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);
+6 -8
View File
@@ -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)
{
+45 -80
View File
@@ -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;
+8 -34
View File
@@ -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;
+1 -4
View File
@@ -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)) {
-1
View File
@@ -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) {
-1
View File
@@ -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
+1 -2
View File
@@ -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);
+5 -8
View File
@@ -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 */
-1
View File
@@ -478,7 +478,6 @@ int main(int argc, char **argv)
logInit();
set_glog(loglvl);
T_stdout = 1;
if (snr1set==0)
snr1 = snr0+10;
+1 -2
View File
@@ -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;
+1 -1
View File
@@ -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
+1 -2
View File
@@ -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;
+16 -17
View File
@@ -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;
}
}
+22 -22
View File
@@ -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;
+1
View File
@@ -6,3 +6,4 @@ add_subdirectory(F1AP)
add_subdirectory(M2AP)
add_subdirectory(X2AP)
add_subdirectory(RRC)
add_subdirectory(XNAP)
+1
View File
@@ -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
+7 -2
View File
@@ -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);
+41 -38
View File
@@ -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