diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..6757ed47f6 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "enter program name, for example ${workspaceFolder}/a.exe", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/path/to/gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 86e9cdf74b..4060a1f749 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -131,8 +131,8 @@ pipeline { [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.FlexRanRtcGitLabRepository_Credentials}", usernameVariable: 'git_username', passwordVariable: 'git_password'] ]) { sh "git clone https://${git_username}:${git_password}@gitlab.eurecom.fr/flexran/flexran-rtc.git . > ../git_clone.log 2>&1" + sh "git checkout develop >> ../git_clone.log 2>&1" } - sh "sed -i -e 's#add-apt-repository.*cleishm.*neo4j#add-apt-repository ppa:cleishm/neo4j -y#' -e 's#libneo4j-client-dev#libneo4j-client-dev -y#' tools/install_dependencies" sh "zip -r -qq flexran.zip ." } } diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index 076e90fc2d..ef2637965f 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -72,7 +72,7 @@ function build_on_vm { echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" acquire_vm_create_lock - uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml + uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk 10 --unsafe-caching --template ci-scripts/template-host.xml echo "Waiting for VM to be started" uvt-kvm wait $VM_NAME --insecure @@ -179,8 +179,12 @@ function build_on_vm { echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS echo "echo \"./tools/install_dependencies \"" >> $VM_CMDS echo "./tools/install_dependencies > cmake_targets/log/install-build.txt 2>&1" >> $VM_CMDS + echo "echo \"mkdir build\"" >> $VM_CMDS + echo "mkdir build" >> $VM_CMDS + echo "echo \"cd build\"" >> $VM_CMDS + echo "cd build" >> $VM_CMDS echo "echo \"$BUILD_OPTIONS \"" >> $VM_CMDS - echo "$BUILD_OPTIONS > cmake_targets/log/rt_controller.Rel15.txt 2>&1" >> $VM_CMDS + echo "$BUILD_OPTIONS > ../cmake_targets/log/rt_controller.Rel15.txt 2>&1" >> $VM_CMDS fi if [[ "$VM_NAME" != *"-cppcheck"* ]] && [[ "$VM_NAME" != *"-flexran-rtc"* ]] then diff --git a/ci-scripts/createVM.sh b/ci-scripts/createVM.sh index e0e1da4236..b1d2346392 100755 --- a/ci-scripts/createVM.sh +++ b/ci-scripts/createVM.sh @@ -90,7 +90,7 @@ function create_vm { echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" acquire_vm_create_lock - uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml + uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk 10 --unsafe-caching --template ci-scripts/template-host.xml echo "Waiting for VM to be started" uvt-kvm wait $VM_NAME --insecure diff --git a/ci-scripts/main.py b/ci-scripts/main.py index fc7d2090db..aaa7ede62a 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -372,7 +372,7 @@ class SSHConnection(): self.air_interface = 'lte' self.command('mkdir -p ' + lSourcePath, '\$', 5) self.command('cd ' + lSourcePath, '\$', 5) - self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) + self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) # Raphael: here add a check if git clone or git fetch went smoothly self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) self.command('git config user.name "OAI Jenkins"', '\$', 5) @@ -537,7 +537,7 @@ class SSHConnection(): ue_prefix = '' self.command('mkdir -p ' + self.UESourceCodePath, '\$', 5) self.command('cd ' + self.UESourceCodePath, '\$', 5) - self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) + self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) # here add a check if git clone or git fetch went smoothly self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) self.command('git config user.name "OAI Jenkins"', '\$', 5) diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 02e031a52f..ce40134cec 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -185,7 +185,7 @@ function variant__v3__phy_sim { NB_PATTERN_FILES=12 BUILD_OPTIONS="--phy_simulators" VM_MEMORY=8192 - RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" + RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111\" -q -np -b" } function variant__v4__cppcheck { @@ -222,7 +222,7 @@ function variant__v8__ue_ethernet { function variant__v10__flexran_rtc { ARCHIVES_LOC=flexran NB_PATTERN_FILES=1 - BUILD_OPTIONS="cmake . && make -j2" + BUILD_OPTIONS="cmake .. && make -j2" VARIANT_INFO="non-OSA" } diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh index 9626e36551..f066dacd81 100755 --- a/ci-scripts/waitBuildOnVM.sh +++ b/ci-scripts/waitBuildOnVM.sh @@ -76,6 +76,8 @@ function wait_on_vm_build { echo "echo \"ps -aux | grep build \"" >> $VM_CMDS echo "while [ \$(ps -aux | grep --color=never build_oai | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS fi + echo "echo \"df -h\"" >> $VM_CMDS + echo "df -h" >> $VM_CMDS ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS rm -f $VM_CMDS diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 3efb260c6d..273aad0c20 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -185,7 +185,7 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,${CMAKE_CU # set a flag for changes in the source code # these changes are related to hardcoded path to include .h files set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3 -O2") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g3 -DMALLOC_CHECK_=3 -O2") set(GIT_BRANCH "UNKNOWN") @@ -1713,10 +1713,6 @@ add_dependencies(L2_UE rrc_flag s1ap_flag x2_flag) add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} ) -add_library ( LTE_NR_L2_UE - ${LTE_NR_L2_SRC_UE} - ) - add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_mac_common.c ) include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE") @@ -2303,6 +2299,10 @@ add_library(minimal_lib ) target_link_libraries(minimal_lib pthread dl ${T_LIB}) +add_executable(nfapi_test + ${OPENAIR_DIR}/openair2/NR_PHY_INTERFACE/nfapi_5g_test.c + ) + add_executable(replay_node ${OPENAIR_TARGETS}/ARCH/rfsimulator/stored_node.c ) @@ -2465,42 +2465,6 @@ target_link_libraries (nr-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRY target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-softmodem ${T_LIB}) -# nr-softmodem-nos1 -################################################### - -add_executable(nr-softmodem-nos1 - ${rrc_h} - ${s1ap_h} -# ${OPENAIR_BIN_DIR}/messages_xml.h - ${OPENAIR_DIR}/executables/nr-gnb.c - ${OPENAIR_DIR}/executables/nr-ru.c - ${OPENAIR_DIR}/executables/nr-softmodem.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${OPENAIR2_DIR}/RRC/NAS/nas_config.c - ${OPENAIR2_DIR}/RRC/NAS/rb_config.c - ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c - ${OPENAIR_DIR}/common/utils/utils.c - ${OPENAIR_DIR}/common/utils/system.c - ${GTPU_need_ITTI} - ${XFORMS_SOURCE_NR} - ${T_SOURCE} - ${CONFIG_SOURCES} - ${SHLIB_LOADER_SOURCES} - ) - -target_link_libraries (nr-softmodem-nos1 - -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA - ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} - RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2 L2_NR MAC_NR_COMMON - NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB - -Wl,--end-group z dl) - -target_link_libraries (nr-softmodem-nos1 ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) -target_link_libraries (nr-softmodem-nos1 ${LIB_LMS_LIBRARIES}) -target_link_libraries (nr-softmodem-nos1 ${T_LIB}) # nr-uesoftmodem is UE implementation ####################################### @@ -2539,39 +2503,6 @@ target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${C target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-uesoftmodem ${T_LIB}) -# nr-uesoftmodem-nos1 -####################################### - -add_executable(nr-uesoftmodem-nos1 - ${rrc_h} - ${s1ap_h} -# ${OPENAIR_BIN_DIR}/messages_xml.h - ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c - ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c - ${OPENAIR_DIR}/executables/nr-ue.c - ${OPENAIR_DIR}/executables/nr-uesoftmodem.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c - ${OPENAIR_DIR}/common/utils/utils.c - ${OPENAIR_DIR}/common/utils/system.c - ${XFORMS_SOURCE_NR} - ${T_SOURCE} - ${CONFIG_SOURCES} - ${SHLIB_LOADER_SOURCES} - ) - - -target_link_libraries (nr-uesoftmodem-nos1 - -Wl,--start-group - RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB PHY_COMMON PHY_NR_UE PHY_RU LFDS LTE_NR_L2_UE NR_L2_UE MAC_NR_COMMON - ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} - -Wl,--end-group z dl) - -target_link_libraries (nr-uesoftmodem-nos1 ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-uesoftmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) -target_link_libraries (nr-uesoftmodem-nos1 ${LIB_LMS_LIBRARIES}) -target_link_libraries (nr-uesoftmodem-nos1 ${T_LIB}) # USIM process @@ -2801,10 +2732,10 @@ endforeach(myExe) if (${T_TRACER}) foreach(i #all "add_executable" definitions (except tests, rb_tool, updatefw) - lte-softmodem lte-uesoftmodem nr-softmodem nr-softmodem-nos1 - nr-uesoftmodem nr-uesoftmodem-nos1 dlsim dlsim_tm4 dlsim_tm7 + lte-softmodem lte-uesoftmodem nr-softmodem + nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim - syncsim ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim + syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim nr_ulschsim ldpctest polartest smallblocktest cu_test du_test #all "add_library" definitions ITTI RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP_LIB diff --git a/cmake_targets/autotests/README.txt b/cmake_targets/autotests/README.txt index b94d99bff7..10c14fd59a 100644 --- a/cmake_targets/autotests/README.txt +++ b/cmake_targets/autotests/README.txt @@ -96,11 +96,41 @@ Obj.# Case# Test# Description (Test 4, 10 MHz, R3-1.FDD (MCS 16), AWGN, 12dB (70%)), (Test 5, 20 MHz, FDD (MCS 5), AWGN, 6dB (70%)), (Test 6, 20 MHz, FDD (MCS 16), AWGN, 12 dB (70%)) -01 51 02 pucchsim (TBD) -01 51 03 prachsim (TBD) -01 51 04 pdcchsim (TBD) -01 51 05 pbchsim (TBD) -01 51 06 mbmssim (TBD) +01 51 02 ldpc Test cases. (Test1: block length = 3872), + (Test2: block length = 4224), + (Test3: block length = 4576), + (Test4: block length = 4928), + (Test5: block length = 5280), + (Test6: block length = 5632), + (Test7: block length = 6336), + (Test8: block length = 7040), + (Test9: block length = 7744), + (Test10: block length = 8448) +01 51 03 polartest Test cases. (Test1: PBCH polar test), + (Test2: DCI polar test) +01 51 04 nr_pbchsim Test cases. (Test1: PBCH-only, 106 PRB), + (Test2: PBCH and synchronization, 106PBR), + (Test3: PBCH-only, 217 PRB), + (Test4: PBCH and synchronization, 217 RPB), + (Test5: PBCH-only, 273 PRB), + (Test6: PBCH and synchronization, 273 PRB) +01 51 05 nr_dlsim Test cases. (Test1: 106 PRB), + (Test2: 217 PRB), + (Test3: 273 PRB) +01 51 06 nr_dlschsim Test cases. (Test1: 106 PRB), + (Test2: 217 PRB), + (Test3: 273 PRB) +01 51 07 shortblocktest Test cases. (Test1: 3 bits), + (Test2: 6 bits), + (Test3: 7 bits), + (Test4: 11 bits) +01 51 08 nr_ulschsim Test cases. (Test1: 106 PRB), + (Test2: 217 PRB), + (Test3: 273 PRB) +01 51 09 nr_pucchsim Test cases. (Test1: Format 0 ACK miss 106 PRB), + (Test2: Format 1 ACK miss 106 PRB), + (Test3: Format 1 ACK miss 273 PRB), + (Test4: Format 1 NACKtoACK 106 PRB) 01 51 10 dlsim_tm4 test cases (Test 1: 10 MHz, R2.FDD (MCS 5), EVA5, -1dB), (Test 5: 1.4 MHz, R4.FDD (MCS 4), EVA5, 0dB (70%)), (Test 6: 10 MHz, R3.FDD (MCS 15), EVA5, 6.7dB (70%)), @@ -110,8 +140,11 @@ Obj.# Case# Test# Description (Test 10: 5 MHz, R6.FDD (MCS 25), EVA5, 17.4 dB (70%)), (Test 10b: 5 MHz, R6-1.FDD (MCS 24,18 PRB), EVA5, 17.5dB (70%)), (Test 11: 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%)) - (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)), - (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)), + (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)), + (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)), +01 51 11 nr_ulsim Test cases. (Test1: MCS 9), + (Test2: MCS 16), + (Test3: MCS 28) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index d30537424b..a407171d01 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1081,18 +1081,35 @@ execution nr_dlsim Test cases. (Test1: 106 PRB), (Test2: 217 PRB), - (Test3: 273 PRB) + (Test3: 273 PRB), + (Test4: 106 PRB 12 CSET-Offset), + (Test5: 217 PRB 48 CSET-Offset), + (Test6: 106 PRB 25 PDSCH-Offset), + (Test7: 106 PRB 51 PDSCH-Offset), + (Test8: 217 PRB 100 PDSCH-PRBs), + (Test9: 217 PRB 80 PDSCH-Offset), + (Test10: 217 PRB 100 PDSCH-PRBs 80 PDSCH-Offset), + (Test11: 106 PRBs 50 PDSCH-PRBs MCS Index 28 $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash $OPENAIR_DIR/targets/bin/nr_dlsim.Rel15 - -n100 -R106 - -n100 -R217 - -n100 -R273 - nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 - PDCCH test OK + -n100 -R106 -b106 + -n100 -R217 -b217 + -n100 -R273 -b273 + -n100 -R106 -o12 + -n100 -R217 -o48 + -n100 -R106 -a25 + -n100 -R106 -a51 + -n100 -R217 -b100 + -n100 -R217 -a80 + -n100 -R217 -a80 -b100 + -n100 -e28 + nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 + nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 + PDSCH test OK segmentation fault|assertion|exiting|fatal 3 @@ -1220,6 +1237,30 @@ 3 + + execution + nr_ulsim Test cases. (Test1: MCS 9 106 PRBs), + (Test2: MCS 16 50 PRBs), + (Test3: MCS 28 50 PRBs), + (Test4: MCS 9 217 PRBs), + (Test5: MCS 9 273 PRBs) + + $OPENAIR_DIR/cmake_targets/build_oai + --phy_simulators -c + $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash + + $OPENAIR_DIR/targets/bin/nr_ulsim.Rel15 + -f100 -m9 -r106 -s10 + -f100 -m16 -s20 + -f100 -m28 -s30 + -f100 -m9 -R217 -r217 -s10 + -f100 -m9 -R273 -r273 -s10 + nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 + PUSCH test OK + segmentation fault|assertion|exiting|fatal + 3 + + lte-softmodem diff --git a/common/utils/threadPool/Makefile b/common/utils/threadPool/Makefile index af0b44996c..6b28eb2ba8 100644 --- a/common/utils/threadPool/Makefile +++ b/common/utils/threadPool/Makefile @@ -1,8 +1,13 @@ -all: measurement_display thread-pool-test +all: +measurement_display thread-pool-test -measurement_display: measurement_display.c thread-pool.h - gcc measurement_display.c -I ${OPENAIR_DIR}/ -I ${OPENAIR_DIR}/common/utils/ -I. ${OPENAIR_DIR}/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o measurement_display +measurement_display: +measurement_display.c thread-pool.h +gcc measurement_display.c -I $ {OPENAIR_DIR}/ -I $ {OPENAIR_DIR}/common/utils/ -I. $ {OPENAIR_DIR}/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o +measurement_display -thread-pool-test: thread-pool.c thread-pool.h - gcc -g thread-pool.c -I ${OPENAIR_DIR}/ -I ${OPENAIR_DIR}/common/utils/ -I. ${OPENAIR_DIR}/common/utils/backtrace.c -I ${OPENAIR_DIR}/openair2/COMMON ${OPENAIR_DIR}/common/utils/LOG/log.c ${OPENAIR_DIR}/common/config/config_userapi.c ${OPENAIR_DIR}/common/config/config_load_configmodule.c ${OPENAIR_DIR}/common/config/config_cmdline.c -lpthread -ldl -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o thread-pool-test +thread-pool-test: +thread-pool.c thread-pool.h +gcc -g thread-pool.c -I $ {OPENAIR_DIR}/ -I $ {OPENAIR_DIR}/common/utils/ -I. $ {OPENAIR_DIR}/common/utils/backtrace.c -I $ {OPENAIR_DIR}/openair2/COMMON $ {OPENAIR_DIR}/common/utils/LOG/log.c $ {OPENAIR_DIR}/common/config/config_userapi.c +$ {OPENAIR_DIR}/common/config/config_load_configmodule.c $ {OPENAIR_DIR}/common/config/config_cmdline.c -lpthread -ldl -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o thread-pool-test diff --git a/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c index b45a8fa722..dd3d16d717 100644 --- a/common/utils/threadPool/thread-pool.c +++ b/common/utils/threadPool/thread-pool.c @@ -67,7 +67,7 @@ void *one_thread(void *arg) { delNotifiedFIFO_elt(elt); else pushNotifiedFIFO(elt->reponseFifo, elt); - + myThread->runningOnKey=-1; mutexunlock(tp->incomingFifo.lockF); } } while (true); @@ -95,7 +95,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { pool->nbThreads=0; pool->restrictRNTI=false; curptr=strtok_r(params,",",&saveptr); - + struct one_thread * ptr; while ( curptr!=NULL ) { int c=toupper(curptr[0]); @@ -109,8 +109,9 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { break; default: + ptr=pool->allthreads; pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread)); - pool->allthreads->next=pool->allthreads; + pool->allthreads->next=ptr; printf("create a thread for core %d\n", atoi(curptr)); pool->allthreads->coreID=atoi(curptr); pool->allthreads->id=pool->nbThreads; diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h index d6dc332c5a..9a2681a828 100644 --- a/common/utils/threadPool/thread-pool.h +++ b/common/utils/threadPool/thread-pool.h @@ -150,8 +150,9 @@ static inline notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf) { // This function aborts all messages matching the key // If the queue is used in thread pools, it doesn't cancels already running processing // because the message has already been picked -static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { +static inline int abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { mutexlock(nf->lockF); + int nbDeleted=0; notifiedFIFO_elt_t **start=&nf->outF; while(*start!=NULL) { @@ -159,13 +160,16 @@ static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { notifiedFIFO_elt_t *request=*start; *start=(*start)->next; delNotifiedFIFO_elt(request); - } - - if (*start != NULL) + nbDeleted++; + } else start=&(*start)->next; } + if (nf->outF == NULL) + nf->inF=NULL; + mutexunlock(nf->lockF); + return nbDeleted; } struct one_thread { @@ -195,7 +199,20 @@ typedef struct thread_pool { static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) { if (t->measurePerf) msg->creationTime=rdtsc(); - pushNotifiedFIFO(&t->incomingFifo, msg); + if ( t->activated) + pushNotifiedFIFO(&t->incomingFifo, msg); + else { + if (t->measurePerf) + msg->startProcessingTime=rdtsc(); + + msg->processingFunc(NotifiedFifoData(msg)); + + if (t->measurePerf) + msg->endProcessingTime=rdtsc(); + + if (msg->reponseFifo) + pushNotifiedFIFO(msg->reponseFifo, msg); + } } static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) { @@ -225,7 +242,8 @@ static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpo return msg; } -static inline void abortTpool(tpool_t *t, uint64_t key) { +static inline int abortTpool(tpool_t *t, uint64_t key) { + int nbRemoved=0; notifiedFIFO_t *nf=&t->incomingFifo; mutexlock(nf->lockF); notifiedFIFO_elt_t **start=&nf->outF; @@ -235,22 +253,27 @@ static inline void abortTpool(tpool_t *t, uint64_t key) { notifiedFIFO_elt_t *request=*start; *start=(*start)->next; delNotifiedFIFO_elt(request); - } - - if (*start != NULL) + nbRemoved++; + } else start=&(*start)->next; } + if (t->incomingFifo.outF==NULL) + t->incomingFifo.inF=NULL; + struct one_thread *ptr=t->allthreads; while(ptr!=NULL) { - if (ptr->runningOnKey==key) + if (ptr->runningOnKey==key) { ptr->abortFlag=true; + nbRemoved++; + } ptr=ptr->next; } mutexunlock(nf->lockF); + return nbRemoved; } void initTpool(char *params,tpool_t *pool, bool performanceMeas); diff --git a/common/utils/threadPool/thread-pool.md b/common/utils/threadPool/thread-pool.md index 2b6336fb60..bc1b1db54a 100644 --- a/common/utils/threadPool/thread-pool.md +++ b/common/utils/threadPool/thread-pool.md @@ -3,69 +3,90 @@ The thread pool is a working server, made of a set of worker threads that can be mapped on CPU cores. Each worker loop on pick from the same input queue jobs to do. + When a job is done, the worker sends a return if a return is defined. -A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless). + A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless). -All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter. + All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, + so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter. ## license -Author: Laurent Thomas, Open cells project -The owner share this piece code to Openairsoftware alliance as per OSA license terms + Author: + Laurent Thomas, Open cells project + The owner share this piece code to Openairsoftware alliance as per OSA license terms # jobs -A job is a message (notifiedFIFO_elt_t): -next: internal FIFO chain, do not set it -key: a long int that the client can use to identify a message or a group of messages -responseFifo: if the client defines a response FIFO, the message will be posted back after processing -processingFunc: any funtion (type void processingFunc(void *)) that the worker will launch -msgData: the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing -malloced: a boolean that enable internal free in these cases: no return Fifo or Abort feature + A job is a message (notifiedFIFO_elt_t): + next: + internal FIFO chain, do not set it + key: + a long int that the client can use to identify a message or a group of messages + responseFifo: + if the client defines a response FIFO, the message will be posted back after processing + processingFunc: + any funtion (type void processingFunc(void *)) that the worker will launch + msgData: + the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing + malloced: + a boolean that enable internal free in these cases: + no return Fifo or Abort feature -The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client. + The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client. # Queues of jobs -Queues are type of: notifiedFIFO_t that must be initialized by init_notifiedFIFO() -No delete function is required, the creator has only to free the data of type notifiedFIFO_t + Queues are type of: + notifiedFIFO_t that must be initialized by init_notifiedFIFO() + No delete function is required, the creator has only to free the data of type notifiedFIFO_t -push_notifiedFIFO() add a job in the queue -pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking + push_notifiedFIFO() add a job in the queue + pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking -abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition) + abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition) # Thread pools ## initialization -The clients can create one or more thread pools with init_tpool() -the params string structure: describes a list of cores, separated by "," that run a worker thread + The clients can create one or more thread pools with init_tpool() + the params string structure: + describes a list of cores, separated by "," that run a worker thread -If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and the related code (use negative values is allowed, so the thread will never be mapped on a specific core). + If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and + the related code (use negative values is allowed, so the thread will never be mapped on a specific core). -The threads are all Linux real time scheduler, their name is set automatically is "Tpool_" + The threads are all Linux real time scheduler, their name is set automatically is "Tpool_" ## adding jobs -The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO()) + The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO()) -If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job. + If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job. ## abort -A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues. + A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues. -Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue. + Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue. ## Performance measurements -A performance measurement is integrated: the pool will automacillay fill timestamps: + A performance measurement is integrated: + the pool will automacillay fill timestamps: -* creationTime: time the request is push to the pool; -* startProcessingTime: time a worker start to run on the job -* endProcessingTime: time the worker finished the job -* returnTime: time the client reads the result + * creationTime: + time the request is push to the pool; -if you set the environement variable: thread-pool-measurements to a valid file name +* startProcessingTime: +time a worker start to run on the job +* endProcessingTime: +time the worker finished the job +* returnTime: +time the client reads the result + +if you set the environement variable: +thread-pool-measurements to a valid file name These measurements will be wrote to this Linux pipe. -A tool to read the linux fifo and display it in ascii is provided: see the local directory Makefile for this tool and to compile the thread pool unitary tests. +A tool to read the linux fifo and display it in ascii is provided: +see the local directory Makefile for this tool and to compile the thread pool unitary tests. diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 43a3aa9195..cb1d45adc2 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -194,11 +194,6 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t // UE-specific RX processing for subframe n if (nfapi_mode == 0 || nfapi_mode == 1) */ - if (slot_rx == NR_UPLINK_SLOT || gNB->frame_parms.frame_type == FDD) { - nfapi_nr_ul_config_ulsch_pdu_rel15_t *ulsch_pdu_rel15 = &gNB->ulsch[1][0]->harq_processes[0]->ulsch_pdu.ulsch_pdu_rel15; - phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx, ulsch_pdu_rel15->start_symbol, ulsch_pdu_rel15->start_symbol + ulsch_pdu_rel15->number_symbols); - } - pthread_mutex_lock(&gNB->UL_INFO_mutex); gNB->UL_INFO.frame = frame_rx; gNB->UL_INFO.slot = slot_rx; @@ -217,6 +212,9 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t if (oai_exit) return(-1); + //if (slot_rx == NR_UPLINK_SLOT || gNB->frame_parms.frame_type == FDD) + phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); + if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) { phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); } @@ -528,7 +526,7 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { int ret; int i; struct timespec abstime; - int time_ns = 10000; + int time_ns = 50000; AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret); for (i=0;inum_RU;i++) { @@ -956,7 +954,8 @@ void init_gNB(int single_thread_flag,int wait_for_sync) { gNB->if_inst->NR_Schedule_response = nr_schedule_response; gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO)); - memset((void *)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO)); + memset((void *)&gNB->UL_tti_req,0,sizeof(nfapi_nr_ul_tti_request_t)); + //memset((void *)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO)); LOG_I(PHY,"Setting indication lists\n"); gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = gNB->rx_pdu_list; gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = gNB->crc_pdu_list; @@ -964,6 +963,7 @@ void init_gNB(int single_thread_flag,int wait_for_sync) { gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list; gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list; gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list; + gNB->prach_energy_counter = 0; } } diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 85a3dad4c9..1cdcf21896 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -81,6 +81,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "enb_config.h" +#include #ifdef SMBV #include "PHY/TOOLS/smbv.h" @@ -727,13 +728,15 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { //nr_subframe_t SF_type = nr_slot_select(cfg,slot%fp->slots_per_frame); if ((slot == 0) || - (slot == 1)) { + (slot == 1) || IS_SOFTMODEM_RFSIM ) { int siglen=fp->samples_per_slot; int flags; if (slot==0) flags = 2; else if (slot==1) flags=3; + else + flags=4; /* if (SF_type == SF_S) { diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index 57d7377134..5d259eb251 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -49,10 +49,12 @@ #define SOFTMODEM_NOS1_BIT (1<<0) #define SOFTMODEM_NOKRNMOD_BIT (1<<1) +#define SOFTMODEM_RFSIM_BIT (1<<10) #define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT) #define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT) +#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT) extern uint64_t get_softmodem_optmask(void); extern void get_common_options(void); diff --git a/executables/nr-ue.c b/executables/nr-ue.c index daa07980e2..fcbd659bbe 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -538,6 +538,9 @@ void trashFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { dummy_rx, UE->frame_parms.samples_per_subframe, UE->frame_parms.nb_antennas_rx); + if (IS_SOFTMODEM_RFSIM ) { + usleep(1000); // slow down, as would do actuall rf to let cpu for the synchro thread + } } for (int i=0; iframe_parms.nb_antennas_tx; i++) @@ -695,12 +698,12 @@ void *UE_thread(void *arg) { //LOG_I(PHY,"Process slot %d thread Idx %d total gain %d\n", slot_nr, thread_idx, UE->rx_total_gain_dB); #ifdef OAI_ADRV9371_ZC706 - uint32_t total_gain_dB_prev = 0; + /*uint32_t total_gain_dB_prev = 0; if (total_gain_dB_prev != UE->rx_total_gain_dB) { total_gain_dB_prev = UE->rx_total_gain_dB; - openair0_cfg[0].rx_gain[0] = UE->rx_total_gain_dB-20; + openair0_cfg[0].rx_gain[0] = UE->rx_total_gain_dB; UE->rfdevice.trx_set_gains_func(&UE->rfdevice,&openair0_cfg[0]); - } + }*/ #endif for (int i=0; iframe_parms.nb_antennas_rx; i++) @@ -732,6 +735,8 @@ void *UE_thread(void *arg) { rxp, readBlockSize, UE->frame_parms.nb_antennas_rx),""); + +if (slot_nr==18) AssertFatal( writeBlockSize == UE->rfdevice.trx_write_func(&UE->rfdevice, timestamp+ @@ -741,7 +746,7 @@ void *UE_thread(void *arg) { txp, writeBlockSize, UE->frame_parms.nb_antennas_tx, - 1),""); + 4),""); if( slot_nr==(nb_slot_frame-1)) { // read in first symbol of next frame and adjust for timing drift diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h index aad688c9d4..e85caf7690 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h @@ -586,13 +586,14 @@ typedef struct { uint8_t start_symbol; uint8_t nb_symbols; uint8_t mcs_idx; + uint8_t mcs_table; uint8_t ndi; uint8_t nb_codewords; uint8_t nb_layers; uint16_t coding_rate; uint8_t modulation; uint8_t modulation_order; - uint16_t transport_block_size; + uint32_t transport_block_size; uint8_t nb_re_dmrs; uint8_t time_alloc_list_flag; uint8_t time_alloc_list; @@ -694,6 +695,7 @@ typedef struct { nr_pusch_freq_hopping_t pusch_freq_hopping; uint8_t mcs; uint8_t Qm; + uint16_t R; uint8_t ndi; uint8_t rv; int8_t accumulated_delta_PUSCH; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h new file mode 100644 index 0000000000..1eea6474f3 --- /dev/null +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -0,0 +1,1402 @@ +/* + nfapi_nr_interface.h + ------------------- + AUTHOR : Chenyu Zhang, Florian Kaltenberger + COMPANY : BUPT, EURECOM + EMAIL : octopus@bupt.edu.cn, florian.kaltenberger@eurecom.fr +*/ + +#ifndef _NFAPI_NR_INTERFACE_SCF_H_ +#define _NFAPI_NR_INTERFACE_SCF_H_ + +#include "stddef.h" +#include "nfapi_interface.h" + +#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5 +#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64 +#define NFAPI_NR_MAX_NB_CORESETS 12 +#define NFAPI_NR_MAX_NB_SEARCH_SPACES 40 + +#define NFAPI_MAX_NUM_UL_UE_PER_GROUP 6 +#define NFAPI_MAX_NUM_UL_PDU 8 +#define NFAPI_MAX_NUM_GROUPS 8 +#define NFAPI_MAX_NUM_CB 8 + +/* +// Extension to the generic structures for single tlv values +typedef struct { + nfapi_tl_t tl; + int32_t value; +} nfapi_int32_tlv_t; + +typedef struct { + nfapi_tl_t tl; + uint32_t value; +} nfapi_uint32_tlv_t; +*/ + +// 2019.8 +// SCF222_5G-FAPI_PHY_SPI_Specificayion.pdf Section 3.2 + +//PHY API message types + +typedef enum { + NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST= 0x00, + NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE= 0x01, + NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST= 0x02, + NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE=0X03, + NFAPI_NR_PHY_MSG_TYPE_START_REQUEST= 0X04, + NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST= 0X05, + NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION=0X06, + NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION=0X07, + //RESERVED 0X08 ~ 0X7F + NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST= 0X80, + NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST= 0X81, + NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION=0X82, + NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST= 0X83, + NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST=0X54, + NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION=0X85, + NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION= 0X86, + NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION= 0X87, + NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION= 0X88, + NFAPI_NR_PHY_MSG_TYPE_PACH_INDICATION= 0X89 + //RESERVED 0X8a ~ 0xff +} nfapi_nr_phy_msg_type_e; + +// SCF222_5G-FAPI_PHY_SPI_Specificayion.pdf Section 3.3 + +//3.3.1 PARAM + +typedef struct { + nfapi_tl_t tl; + uint16_t value; + +} nfapi_nr_param_tlv_t; + +//same with nfapi_param_request_t +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_param_request_t; + +typedef enum { + NFAPI_NR_PARAM_MSG_OK = 0, + NFAPI_NR_PARAM_MSG_INVALID_STATE + +} nfapi_nr_param_errors_e; + +typedef struct { + nfapi_nr_param_errors_e error_code; + //Number of TLVs contained in the message body. + uint8_t number_of_tlvs; + nfapi_nr_param_tlv_t TLV; +} nfapi_nr_param_response_t; + + +//PARAM and CONFIG TLVs are used in the PARAM and CONFIG message exchanges, respectively + + +//nfapi_nr_param_tlv_format_t cell param ~ measurement_param: + +//table 3-9 + +#define NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG 0x0001 +#define NFAPI_NR_PARAM_TLV_PHY_STATE_TAG 0x0002 +#define NFAPI_NR_PARAM_TLV_SKIP_BLANK_DL_CONFIG_TAG 0x0003 +#define NFAPI_NR_PARAM_TLV_SKIP_BLANK_UL_CONFIG_TAG 0x0004 +#define NFAPI_NR_PARAM_TLV_NUM_CONFIG_TLVS_TO_REPORT_TAG 0x0005 +#define NFAPI_NR_PARAM_TLV_CYCLIC_PREFIX_TAG 0x0006 +#define NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_DL_TAG 0x0007 +#define NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_DL_TAG 0x0008 +#define NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_UL_TAG 0x0009 +#define NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_UL_TAG 0x000A +#define NFAPI_NR_PARAM_TLV_CCE_MAPPING_TYPE_TAG 0x000B +#define NFAPI_NR_PARAM_TLV_CORESET_OUTSIDE_FIRST_3_OFDM_SYMS_OF_SLOT_TAG 0x000C +#define NFAPI_NR_PARAM_TLV_PRECODER_GRANULARITY_CORESET_TAG 0x000D +#define NFAPI_NR_PARAM_TLV_PDCCH_MU_MIMO_TAG 0x000E +#define NFAPI_NR_PARAM_TLV_PDCCH_PRECODER_CYCLING_TAG 0x000F +#define NFAPI_NR_PARAM_TLV_MAX_PDCCHS_PER_SLOT_TAG 0x0010 +#define NFAPI_NR_PARAM_TLV_PUCCH_FORMATS_TAG 0x0011 +#define NFAPI_NR_PARAM_TLV_MAX_PUCCHS_PER_SLOT_TAG 0x0012 +#define NFAPI_NR_PARAM_TLV_PDSCH_MAPPING_TYPE_TAG 0x0013 +#define NFAPI_NR_PARAM_TLV_PDSCH_ALLOCATION_TYPES_TAG 0x0014 +#define NFAPI_NR_PARAM_TLV_PDSCH_VRB_TO_PRB_MAPPING_TAG 0x0015 +#define NFAPI_NR_PARAM_TLV_PDSCH_CBG_TAG 0x0016 +#define NFAPI_NR_PARAM_TLV_PDSCH_DMRS_CONFIG_TYPES_TAG 0x0017 +#define NFAPI_NR_PARAM_TLV_PDSCH_DMRS_MAX_LENGTH_TAG 0x0018 +#define NFAPI_NR_PARAM_TLV_PDSCH_DMRS_ADDITIONAL_POS_TAG 0x0019 +#define NFAPI_NR_PARAM_TLV_MAX_PDSCH_S_YBS_PER_SLOT_TAG 0x001A +#define NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_PDSCH_TAG 0x001B +#define NFAPI_NR_PARAM_TLV_SUPPORTED_MAX_MODULATION_ORDER_DL_TAG 0x001C +#define NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_DL_TAG 0x001D +#define NFAPI_NR_PARAM_TLV_PDSCH_DATA_IN_DMRS_SYMBOLS_TAG 0x001E +#define NFAPI_NR_PARAM_TLV_PREMPTION_SUPPORT_TAG 0x001F +#define NFAPI_NR_PARAM_TLV_PDSCH_NON_SLOT_SUPPORT_TAG 0x0020 +#define NFAPI_NR_PARAM_TLV_UCI_MUX_ULSCH_IN_PUSCH_TAG 0x0021 +#define NFAPI_NR_PARAM_TLV_UCI_ONLY_PUSCH_TAG 0x0022 +#define NFAPI_NR_PARAM_TLV_PUSCH_FREQUENCY_HOPPING_TAG 0x0023 +#define NFAPI_NR_PARAM_TLV_PUSCH_DMRS_CONFIG_TYPES_TAG 0x0024 +#define NFAPI_NR_PARAM_TLV_PUSCH_DMRS_MAX_LEN_TAG 0x0025 +#define NFAPI_NR_PARAM_TLV_PUSCH_DMRS_ADDITIONAL_POS_TAG 0x0026 +#define NFAPI_NR_PARAM_TLV_PUSCH_CBG_TAG 0x0027 +#define NFAPI_NR_PARAM_TLV_PUSCH_MAPPING_TYPE_TAG 0x0028 +#define NFAPI_NR_PARAM_TLV_PUSCH_ALLOCATION_TYPES_TAG 0x0029 +#define NFAPI_NR_PARAM_TLV_PUSCH_VRB_TO_PRB_MAPPING_TAG 0x002A +#define NFAPI_NR_PARAM_TLV_PUSCH_MAX_PTRS_PORTS_TAG 0x002B +#define NFAPI_NR_PARAM_TLV_MAX_PDUSCHS_TBS_PER_SLOT_TAG 0x002C +#define NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_NON_CB_PUSCH_TAG 0x002D +#define NFAPI_NR_PARAM_TLV_SUPPORTED_MODULATION_ORDER_UL_TAG 0x002E +#define NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_UL_TAG 0x002F +#define NFAPI_NR_PARAM_TLV_DFTS_OFDM_SUPPORT_TAG 0x0030 +#define NFAPI_NR_PARAM_TLV_PUSCH_AGGREGATION_FACTOR_TAG 0x0031 +#define NFAPI_NR_PARAM_TLV_PRACH_LONG_FORMATS_TAG 0x0032 +#define NFAPI_NR_PARAM_TLV_PRACH_SHORT_FORMATS_TAG 0x0033 +#define NFAPI_NR_PARAM_TLV_PRACH_RESTRICTED_SETS_TAG 0x0034 +#define NFAPI_NR_PARAM_TLV_MAX_PRACH_FD_OCCASIONS_IN_A_SLOT_TAG 0x0035 +#define NFAPI_NR_PARAM_TLV_RSSI_MEASUREMENT_SUPPORT_TAG 0x0036 + +typedef struct +{ + uint16_t release_capability; //TAG 0x0001 + uint16_t phy_state; + uint8_t skip_blank_dl_config; + uint8_t skip_blank_ul_config; + uint16_t num_config_tlvs_to_report; + nfapi_nr_param_tlv_t* config_tlvs_to_report_list; +} nfapi_nr_cell_param_t; + +//table 3-10 Carrier parameters +typedef struct +{ + uint8_t cyclic_prefix;//TAG 0x0006 + uint8_t supported_subcarrier_spacings_dl; + uint16_t supported_bandwidth_dl; + uint8_t supported_subcarrier_spacings_ul; + uint16_t supported_bandwidth_ul; + +} nfapi_nr_carrier_param_t; + +//table 3-11 PDCCH parameters +typedef struct +{ + uint8_t cce_mapping_type; + uint8_t coreset_outside_first_3_of_ofdm_syms_of_slot; + uint8_t coreset_precoder_granularity_coreset; + uint8_t pdcch_mu_mimo; + uint8_t pdcch_precoder_cycling; + uint8_t max_pdcch_per_slot;//TAG 0x0010 + +} nfapi_nr_pdcch_param_t; + +//table 3-12 PUCCH parameters +typedef struct +{ + uint8_t pucch_formats; + uint8_t max_pucchs_per_slot; + +} nfapi_nr_pucch_param_t; + +//table 3-13 PDSCH parameters +typedef struct +{ + uint8_t pdsch_mapping_type; + uint8_t pdsch_allocation_types; + uint8_t pdsch_vrb_to_prb_mapping; + uint8_t pdsch_cbg; + uint8_t pdsch_dmrs_config_types; + uint8_t pdsch_dmrs_max_length; + uint8_t pdsch_dmrs_additional_pos; + uint8_t max_pdsch_tbs_per_slot; + uint8_t max_number_mimo_layers_pdsch; + uint8_t supported_max_modulation_order_dl; + uint8_t max_mu_mimo_users_dl; + uint8_t pdsch_data_in_dmrs_symbols; + uint8_t premption_support;//TAG 0x001F + uint8_t pdsch_non_slot_support; + +} nfapi_nr_pdsch_param_t; + +//table 3-14 +typedef struct +{ + uint8_t uci_mux_ulsch_in_pusch; + uint8_t uci_only_pusch; + uint8_t pusch_frequency_hopping; + uint8_t pusch_dmrs_config_types; + uint8_t pusch_dmrs_max_len; + uint8_t pusch_dmrs_additional_pos; + uint8_t pusch_cbg; + uint8_t pusch_mapping_type; + uint8_t pusch_allocation_types; + uint8_t pusch_vrb_to_prb_mapping; + //uint8 ? ↓ see table 3-14 + uint8_t pusch_max_ptrs_ports; + uint8_t max_pduschs_tbs_per_slot; + uint8_t max_number_mimo_layers_non_cb_pusch; + uint8_t supported_modulation_order_ul; + uint8_t max_mu_mimo_users_ul; + uint8_t dfts_ofdm_support; + uint8_t pusch_aggregation_factor;//TAG 0x0031 + +} nfapi_nr_pusch_param_t; + +//table 3-15 +typedef struct +{ + uint8_t prach_long_formats; + uint8_t prach_short_formats; + uint8_t prach_restricted_sets; + uint8_t max_prach_fd_occasions_in_a_slot; + +} nfapi_nr_prach_param_t; + +//table 3-16 +typedef struct +{ + uint8_t rssi_measurement_support; +} nfapi_nr_measurement_param_t; + +//-------------------------------------------// +//3.3.2 CONFIG +typedef struct { + nfapi_tl_t tl; + uint16_t value; +} nfapi_nr_config_tlv_t; + +typedef struct { + uint8_t number_of_tlvs; + nfapi_nr_config_tlv_t tlv; +} nfapi_nr_config_request_scf_t; + +typedef enum { + NFAPI_NR_CONFIG_MSG_OK = 0, + NFAPI_NR_CONFIG_MSG_INVALID_CONFIG //The configuration provided has missing mandatory TLVs, or TLVs that are invalid or unsupported in this state. +} nfapi_nr_config_errors_e; + +typedef struct { + nfapi_nr_config_errors_e error_code; + uint8_t number_of_invalid_tlvs_that_can_only_be_configured_in_idle; + uint8_t unmber_of_missing_tlvs; + //? ↓ + nfapi_nr_config_tlv_t* tlv_invalid_list; + nfapi_nr_config_tlv_t* tlv_invalid_idle_list; + nfapi_nr_config_tlv_t* tlv_invalid_running_list; + nfapi_nr_config_tlv_t* tlv_missing_list; + +} nfapi_nr_config_response_t; + +//nfapi_nr_config_tlv_format_t carrier config ~ precoding config: + +#define NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG 0x1001 +#define NFAPI_NR_CONFIG_DL_FREQUENCY_TAG 0x1002 +#define NFAPI_NR_CONFIG_DL_K0_TAG 0x1003 +#define NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG 0x1004 +#define NFAPI_NR_CONFIG_NUM_TX_ANT_TAG 0x1005 +#define NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG 0x1006 +#define NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG 0x1007 +#define NFAPI_NR_CONFIG_UL_K0_TAG 0x1008 +#define NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG 0x1009 +#define NFAPI_NR_CONFIG_NUM_RX_ANT_TAG 0x100A +#define NFAPI_NR_CONFIG_FREQUENCY_SHIFT_7P5KHZ_TAG 0x100B + +#define NFAPI_NR_CONFIG_PHY_CELL_ID_TAG 0x100C +#define NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG 0x100D + +#define NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG 0x100E +#define NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG 0x100F +#define NFAPI_NR_CONFIG_SCS_COMMON_TAG 0x1010 + +#define NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG 0x1011 +#define NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG 0x1012 +#define NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG 0x1013 +#define NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG 0x1014 +#define NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG 0x1015 +#define NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG 0x1016 +#define NFAPI_NR_CONFIG_K1_TAG 0x1017 +#define NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG 0x1018 +#define NFAPI_NR_CONFIG_NUM_UNUSED_ROOT_SEQUENCES_TAG 0x1019 +#define NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG 0x101A +#define NFAPI_NR_CONFIG_SSB_PER_RACH_TAG 0x101B +#define NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG 0x101C + +#define NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG 0x101D +#define NFAPI_NR_CONFIG_BETA_PSS_TAG 0x101E +#define NFAPI_NR_CONFIG_SSB_PERIOD_TAG 0x101F +#define NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG 0x1020 +#define NFAPI_NR_CONFIG_MIB_TAG 0x1021 +#define NFAPI_NR_CONFIG_SSB_MASK_TAG 0x1022 +#define NFAPI_NR_CONFIG_BEAM_ID_TAG 0x1023 +#define NFAPI_NR_CONFIG_SS_PBCH_MULTIPLE_CARRIERS_IN_A_BAND_TAG 0x1024 +#define NFAPI_NR_CONFIG_MULTIPLE_CELLS_SS_PBCH_IN_A_CARRIER_TAG 0x1025 +#define NFAPI_NR_CONFIG_TDD_PERIOD_TAG 0x1026 +#define NFAPI_NR_CONFIG_SLOT_CONFIG_TAG 0x1027 + +#define NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG 0x1028 + +//table 3-21 +typedef struct +{ + uint16_t dl_bandwidth;//Carrier bandwidth for DL in MHz [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400 + uint32_t dl_frequency; //Absolute frequency of DL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000 + uint16_t dl_k0[5];//π‘˜_{0}^{πœ‡} for each of the numerologies [38.211, sec 5.3.1] Value: 0 ->23699 + uint16_t dl_grid_size[5];//Grid size 𝑁_{π‘”π‘Ÿπ‘–π‘‘}^{𝑠𝑖𝑧𝑒,πœ‡} for each of the numerologies [38.211, sec 4.4.2] Value: 0->275 0 = this numerology not used + uint16_t num_tx_ant;//Number of Tx antennas + uint16_t uplink_bandwidth;//Carrier bandwidth for UL in MHz. [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400 + uint32_t uplink_frequency;//Absolute frequency of UL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000 + uint16_t ul_k0[5];//π‘˜0 πœ‡ for each of the numerologies [38.211, sec 5.3.1] Value: : 0 ->23699 + uint16_t ul_grid_size[5];//Grid size π‘π‘”π‘Ÿπ‘–π‘‘ 𝑠𝑖𝑧𝑒,πœ‡ for each of the numerologies [38.211, sec 4.4.2]. Value: 0->275 0 = this numerology not used + uint16_t num_rx_ant;// + uint8_t frequency_shift_7p5khz;//Indicates presence of 7.5KHz frequency shift. Value: 0 = false 1 = true + +} nfapi_nr_carrier_config_t; + +//table 3-22 +typedef struct +{ + uint8_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007 + uint8_t frame_duplex_type;//Frame duplex type Value: 0 = FDD 1 = TDD + +} nfapi_nr_cell_config_t; + +//table 3-23 +typedef struct +{ + uint32_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm) + uint8_t bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload + uint8_t scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3 + +} nfapi_nr_ssb_config_t; + +//table 3-24 +/*typedef struct { + uint8_t unused_root_sequences;//Unused root sequence or sequences per FD occasion. Required for noise estimation. +} nfapi_nr_num_unused_root_sequences_t;*/ + +typedef struct +{ + uint8_t num_prach_fd_occasions; + uint16_t prach_root_sequence_index;//Starting logical root sequence index, 𝑖, equivalent to higher layer parameter prach-RootSequenceIndex [38.211, sec 6.3.3.1] Value: 0 -> 837 + uint8_t num_root_sequences;//Number of root sequences for a particular FD occasion that are required to generate the necessary number of preambles + uint16_t k1;//Frequency offset (from UL bandwidth part) for each FD. [38.211, sec 6.3.3.2] Value: from 0 to 272 + uint8_t prach_zero_corr_conf;//PRACH Zero CorrelationZone Config which is used to dervive 𝑁𝑐𝑠 [38.211, sec 6.3.3.1] Value: from 0 to 15 + uint8_t num_unused_root_sequences;//Number of unused sequences available for noise estimation per FD occasion. At least one unused root sequence is required per FD occasion. + uint8_t* unused_root_sequences_list;//Unused root sequence or sequences per FD occasion. Required for noise estimation. + +} nfapi_nr_num_prach_fd_occasions_t; + +typedef struct +{ + uint8_t prach_sequence_length;//RACH sequence length. Long or Short sequence length. Only short sequence length is supported for FR2. [38.211, sec 6.3.3.1] Value: 0 = Long sequence 1 = Short sequence + uint8_t prach_sub_c_spacing;//Subcarrier spacing of PRACH. [38.211 sec 4.2] Value:0->4 + uint8_t restricted_set_config;//PRACH restricted set config Value: 0: unrestricted 1: restricted set type A 2: restricted set type B + uint8_t num_prach_fd_occasions;//Number of RACH frequency domain occasions. Corresponds to the parameter 𝑀 in [38.211, sec 6.3.3.2] which equals the higher layer parameter msg1FDM Value: 1,2,4,8 + nfapi_nr_num_prach_fd_occasions_t* num_prach_fd_occasions_list; + uint8_t ssb_per_rach;//SSB-per-RACH-occasion Value: 0: 1/8 1:1/4, 2:1/2 3:1 4:2 5:4, 6:8 7:16 + uint8_t prach_multiple_carriers_in_a_band;//0 = disabled 1 = enabled + +} nfapi_nr_prach_config_t; + +//table 3-25 +typedef struct +{ + uint32_t ssb_mask;//Bitmap for actually transmitted SSB. MSB->LSB of first 32 bit number corresponds to SSB 0 to SSB 31 MSB->LSB of second 32 bit number corresponds to SSB 32 to SSB 63 Value for each bit: 0: not transmitted 1: transmitted + +} nfapi_nr_ssb_mask_size_2_t; + +typedef struct +{ + uint8_t beam_id[64];//BeamID for each SSB in SsbMask. For example, if SSB mask bit 26 is set to 1, then BeamId[26] will be used to indicate beam ID of SSB 26. Value: from 0 to 63 + +} nfapi_nr_ssb_mask_size_64_t; + +typedef struct +{ + uint16_t ssb_offset_point_a;//Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Given in PRB [38.211, section 4.4.4.2] Value: 0->2199 + uint8_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block [38.213, sec 4.1] Values: 0 = 0dB + uint8_t ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160 + uint8_t ssb_subcarrier_offset;//ssbSubcarrierOffset or π‘˜π‘†π‘†π΅ (38.211, section 7.4.3.1) Value: 0->31 + uint32_t MIB;//MIB payload, where the 24 MSB are used and represent the MIB in [38.331 MIB IE] and represent 0 1 2 3 1 , , , ,..., Aβˆ’ a a a a a [38.212, sec 7.1.1] + nfapi_nr_ssb_mask_size_2_t* ssb_mask_size_2_list;//2 + nfapi_nr_ssb_mask_size_64_t* ssb_mask_size_64_list;//64 + uint8_t ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled + uint8_t multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled + +} nfapi_nr_ssb_table_t; + +//table 3-26 + +//? +typedef struct +{ + uint8_t slot_config;//For each symbol in each slot a uint8_t value is provided indicating: 0: DL slot 1: UL slot 2: Guard slot + +} nfapi_nr_max_num_of_symbol_per_slot_t; + +typedef struct +{ + nfapi_nr_max_num_of_symbol_per_slot_t* max_num_of_symbol_per_slot_list; + +} nfapi_nr_max_tdd_periodicity_t; + +typedef struct +{ + uint8_t tdd_period;//DL UL Transmission Periodicity. Value:0: ms0p5 1: ms0p625 2: ms1 3: ms1p25 4: ms2 5: ms2p5 6: ms5 7: ms10 + nfapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list; + +} nfapi_nr_tdd_table_t; + +//table 3-27 +typedef struct +{ + uint8_t rssi_measurement;//RSSI measurement unit. See Table 3-16 for RSSI definition. Value: 0: Do not report RSSI 1: dBm 2: dBFS + +} nfapi_nr_measurement_config_t; + +//------------------------------// +//3.3.3 START + +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_start_request_t; + +typedef enum { + NFAPI_NR_START_MSG_INVALID_STATE +} nfapi_nr_start_errors_e; + +//3.3.4 STOP + +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_stop_request_t; + +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_stop_indication_t; + +typedef enum { + NFAPI_NR_STOP_MSG_INVALID_STATE +} nfapi_nr_stop_errors_e; + +//3.3.5 PHY Notifications +typedef enum { + NFAPI_NR_PHY_API_MSG_OK =0x0, + NFAPI_NR_PHY_API_MSG_INVALID_STATE =0x1, + NFAPI_NR_PHY_API_MSG_INVALID_CONFIG =0x2, + NFAPI_NR_PHY_API_SFN_OUT_OF_SYNC =0X3, + NFAPI_NR_PHY_API_MSG_SLOR_ERR =0X4, + NFAPI_NR_PHY_API_MSG_BCH_MISSING =0X5, + NFAPI_NR_PHY_API_MSG_INVALID_SFN =0X6, + NFAPI_NR_PHY_API_MSG_UL_DCI_ERR =0X7, + NFAPI_NR_PHY_API_MSG_TX_ERR =0X8 +} nfapi_nr_phy_notifications_errors_e; + +typedef struct { + uint16_t sfn; //0~1023 + uint16_t slot;//0~319 + nfapi_nr_phy_msg_type_e msg_id;//Indicate which message received by the PHY has an error. Values taken from Table 3-4. + nfapi_nr_phy_notifications_errors_e error_code; +} nfapi_nr_phy_notifications_error_indicate_t; + +//-----------------------// +//3.3.6 Storing Precoding and Beamforming Tables + +//table 3-32 +//? +typedef struct { + uint16_t beam_idx; //0~65535 +} nfapi_nr_dig_beam_t; + +typedef struct { + uint16_t dig_beam_weight_Re; + uint16_t dig_beam_weight_Im; +} nfapi_nr_txru_t; + +typedef struct { + uint16_t num_dig_beams; //0~65535 + uint16_t num_txrus; //0~65535 + nfapi_nr_dig_beam_t* dig_beam_list; + nfapi_nr_txru_t* txru_list; +} nfapi_nr_dbt_pdu_t; + + +//table 3-33 +//? +typedef struct { + uint16_t num_ant_ports; + int16_t precoder_weight_Re; + int16_t precoder_weight_Im; +} nfapi_nr_num_ant_ports_t; + +typedef struct { + uint16_t numLayers; //0~65535 + nfapi_nr_num_ant_ports_t* num_ant_ports_list; +} nfapi_nr_num_layers_t; + +typedef struct { + uint16_t pm_idx; //0~65535 + nfapi_nr_num_layers_t* num_layers_list; //0~65535 + //nfapi_nr_num_ant_ports_t* num_ant_ports_list; +} nfapi_nr_pm_pdu_t; + + +// Section 3.4 + +// Section 3.4.1 slot indication +#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_0 1000 //us +#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_1 50 //us +#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_2 250 //us +#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_3 125 //us + +typedef struct { + uint16_t sfn; //0->1023 + uint16_t slot;//0->319 + +} nfapi_nr_slot_indication_t; + +// 3.4.2 + +//for pdcch_pdu: + +typedef struct +{ + uint16_t beam_idx;//Index of the digital beam weight vector pre-stored at cell configuration. The vector maps this input port to output TXRUs. Value: 0->65535 + +}nfapi_nr_dig_bf_interface_t; + +typedef struct +{ + uint16_t pm_idx;//Index to precoding matrix (PM) pre-stored at cell configuration. Note: If precoding is not used this parameter should be set to 0. Value: 0->65535. + nfapi_nr_dig_bf_interface_t* dig_bf_interface_list; + +}nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t; + +//table 3-43 +typedef struct +{ + uint16_t num_prgs;/*Number of PRGs spanning this allocation. +Value : 1->275 */ + uint16_t prg_size;/*Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275 */ + //watchout: dig_bf_interfaces here, in table 3-53 it's dig_bf_interface + uint8_t dig_bf_interfaces;//Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255 + nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t* prgs_list;// + +}nfapi_nr_tx_precoding_and_beamforming_t; + +//table 3-37 + +#define DCI_PAYLOAD_BTYE_LEN 12 //? TS38.212 sec 7.3.1 + +typedef struct +{ + uint16_t rnti;// + uint16_t scrambling_id;// + uint16_t scrambling_rnti;/* */ + uint8_t cce_index;// + uint8_t aggregation_level;// + nfapi_nr_tx_precoding_and_beamforming_t* precoding_and_beamforming_list; + //tx power info + uint8_t beta_pdcch_1_0;/*PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. This is ratio of +SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 */ + uint8_t power_control_offset_ss;//PDCCH power value used for all other PDCCH Formats. This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB + uint16_t payload_size_bits;//The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0-> DCI_PAYLOAD_BTYE_LEN*8 + uint8_t payload[DCI_PAYLOAD_BTYE_LEN];//DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB + +} nfapi_nr_dl_dci_pdu_t; + +//table 3-36 +typedef struct +{ + uint16_t bwp_size;//Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP Value: 1->275 + uint16_t bwp_start;//bandwidth part start RB index from reference CRB [TS38.213 sec 12] Value: 0->274 + uint8_t subcarrier_spacing;//subcarrierSpacing [TS38.211 sec 4.2] Value:0->4 + uint8_t cyclic_prefix;//Cyclic prefix type [TS38.211 sec 4.2] 0: Normal; 1: Extended + //Coreset [TS38.211 sec 7.3.2.2] + uint8_t start_symbol_index;//Starting OFDM symbol for the CORESET Value: 0->13 + uint8_t duration_symbols;/* Contiguous time duration of the CORESET in number of symbols. Corresponds to L1 parameter π‘π‘ π‘¦π‘šπ‘ 𝐢𝑂𝑅𝐸𝑆𝐸𝑇 [TS38.211 sec 7.3.2.2] Value: 1,2,3*/ + uint8_t freq_domain_resource[6];/* Frequency domain resources. This is a bitmap defining non-overlapping groups of 6 PRBs in ascending order. [TS38.213 10.1]. Also, corresponds to L1 parameter N^{CORESET}_{RB} [TS38.211 sec 7.3.2.2] + Bitmap of uint8 array. 45 bits.*/ + uint8_t cce_reg_mapping_type;/*CORESET-CCE-to-REG-mapping-type [TS38.211 sec 7.3.2.2] 0: non-interleaved 1: interleaved */ + uint8_t reg_bundle_size;/*The number of REGs in a bundle. Must be 6 for +cceRegMappingType = nonInterleaved. For cceRegMappingType = interleaved, must belong to {2,6} if duration = 1,2 and must belong to {3,6} if +duration = 3. Corresponds to parameter L. [TS38.211 sec 7.3.2.2] Value: 2,3,6 */ + uint8_t interleaver_size;//The interleaver size. For interleaved mapping belongs to {2,3,6} and for non-interleaved mapping is NA. Corresponds to parameter R. [TS38.211 sec 7.3.2.2] Value: 2,3,6 + uint8_t core_set_type;//[TS38.211 sec 7.3.2.2 and sec 7.4.1.3.2] 0: CORESET is configured by the PBCH or SIB1 (subcarrier 0 of CRB0 for DMRS mapping) 1: otherwise (subcarrier 0 of CORESET) + uint16_t shift_index;//[TS38.211 sec 7.3.2.2] Not applicable for non-interleaved mapping. For interleaved mapping and a PDCCH transmitted in a CORESET configured by the PBCH or SIB1 this should be set to phy cell ID. Value: 10 bits Otherwise, for interleaved mapping this is set to 0-> max num of PRBs. Value 0-> 275 + uint8_t precoder_granularity;//Granularity of precoding [TS38.211 sec 7.3.2.2] 0: sameAsRegBundle 1: allContiguousRBs + uint16_t num_dl_dci;//Number of DCIs in this CORESET. Value: 0->MaxDciPerSlot + nfapi_nr_dl_dci_pdu_t* dl_dci_list; + +} nfapi_nr_pdcch_pdu_t; + +//for pdsch_pdu: + +typedef struct +{ + uint16_t target_code_rate;// + uint8_t qam_mod_order;// + uint8_t mcs_index;// + uint8_t mcs_table;// + uint8_t rv_index;// + uint32_t tb_size;// +} nfapi_nr_code_word_t; + +//table 3-38 +typedef struct +{ + uint16_t pdu_bit_map;//Bitmap indicating presence of optional PDUs Bit 0: pdschPtrs - Indicates PTRS included (FR2) Bit 1:cbgRetxCtrl (Present when CBG based retransmit is used) All other bits reserved + uint16_t rnti;//The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535 + uint16_t pdu_index;// + uint16_t bwp_size;//Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP Value: 1->275 + uint16_t bwp_start;//bandwidth part start RB index from reference CRB [TS38.213 sec 12] Value: 0->274 + uint8_t subcarrier_spacing;//Value:0->4 + uint8_t cyclic_prefix;//0: Normal; 1: Extended + uint8_t nr_of_code_words;//Number of code words for this RNTI (UE) Value: 1 -> 2 + nfapi_nr_code_word_t* code_word_list; + uint16_t data_scrambling_id;// + uint8_t nr_of_layers;// + uint8_t transmission_scheme;//PDSCH transmission schemes [TS38.214, sec 5.1.1] 0: Up to 8 transmission layers + uint8_t ref_point;//Reference point for PDSCH DMRS "k" - used for tone mapping + //DMRS + uint16_t dl_dmrs_symb_pos;//Bitmap occupying the 14 LSBs with: bit 0: first symbol and for each bit 0: no DMRS 1: DMRS + uint8_t dmrs_config_type;//DL DMRS config type[TS38.211, sec 7.4.1.1.2] 0: type 1 1: type 2 + uint16_t dl_dmrs_scrambling_id;//DL-DMRS-Scrambling-ID [TS38.211, sec 7.4.1.1.2 ] If provided by the higher-layer and the PDSCH is scheduled by PDCCH with CRC scrambled by CRNTI or CS-RNTI, otherwise, L2 should set this to physical cell id. Value: 0->65535 + uint8_t scid;// 0 1 + uint8_t num_dmrs_cdm_grps_no_data;//Number of DM-RS CDM groups without data [TS38.212 sec 7.3.1.2.2] [TS38.214 Table 4.1-1] it determines the ratio of PDSCH EPRE to DM-RS EPRE. Value: 1->3 + uint16_t dmrs_ports;//DMRS ports. [TS38.212 7.3.1.2.2] provides description between DCI 1-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used + + //Pdsch Allocation in frequency domain [TS38.214, sec 5.1.2.2] + uint8_t resource_alloc;//Resource Allocation Type [TS38.214, sec 5.1.2.2] 0: Type 0 1: Type 1 + uint8_t rb_bit_map[36];//For resource alloc type 0. TS 38.212 V15.0.x, 7.3.1.2.2 bitmap of RBs, 273 rounded up to multiple of 32. This bitmap is in units of VRBs. LSB of byte 0 of the bitmap represents the first RB of the bwp + uint16_t rb_start;//For resource allocation type 1. [TS38.214, sec5.1.2.2.2] The starting resource block within the BWP for this PDSCH. Value: 0->274 + uint16_t rb_size;//For resource allocation type 1. [TS38.214, sec 5.1.2.2.2] The number of resource block within for this PDSCH. Value: 1->275 + uint8_t vrb_to_prb_mapping;//VRB-to-PRB-mapping [TS38.211, sec 7.3.1.6] 0: non-interleaved 1: interleaved with RB size 2 2: Interleaved with RB size 4 + //Resource Allocation in time domain [TS38.214, sec 5.1.2.1] + uint8_t start_symbol_index;//Start symbol index of PDSCH mapping from the start of the slot, S. [TS38.214, Table 5.1.2.1-1] Value: 0->13 + uint8_t nr_of_symbols;//PDSCH duration in symbols, L [TS38.214, Table 5.1.2.1-1] Value: 1->14 + //PTRS TS38.214 sec 5.1.6.3 + uint8_t ptrs_port_index;//PT-RS antenna ports [TS38.214, sec 5.1.6.3] [TS38.211, table 7.4.1.2.2-1] Bitmap occupying the 6 LSBs with: bit 0: ntenna port 1000 bit 5: antenna port 1005 and for each bit 0: PTRS port not used 1: PTRS port used + uint8_t ptrs_time_density;//PT-RS time density [TS38.214, table 5.1.6.3-1] 0: 1 1: 2 2: 4 + uint8_t ptrs_freq_density;//PT-RS frequency density [TS38.214, table[5.1.6.3-2] 0: 2 1: 4 + uint8_t ptrs_re_offset;//PT-RS resource element offset [TS38.211, table [7.4.1.2.2-1] + uint8_t n_epre_ratio_of_pdsch_to_ptrs;//PT-RS-to-PDSCH EPRE ratio [TS38.214, table 4.1-2] Value :0->3 + nfapi_nr_tx_precoding_and_beamforming_t* precoding_and_beamforming_list; + //TX power info + uint8_t power_control_offset;//Ratio of PDSCH EPRE to NZP CSI-RSEPRE [TS38.214, sec 5.2.2.3.1] Value :0->23 representing -8 to 15 dB in 1dB steps + uint8_t power_control_offset_ss;//Ratio of SSB/PBCH block EPRE to NZP CSI-RS EPRES [TS38.214, sec 5.2.2.3.1] Values: 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB + //CBG fields + uint8_t is_last_cb_present;//Indicates whether last CB is present in the CBG retransmission 0: CBG retransmission does not include last CB 1: CBG retransmission includes last CB If CBG Re-Tx includes last CB, L1 will add the TB CRC to the last CB in the payload before it is read into the LDPC HW unit + uint8_t is_inline_tb_crc;//Indicates whether TB CRC is part of data payload or control message 0: TB CRC is part of data payload 1: TB CRC is part of control message + uint32_t dl_tb_crc;//TB CRC: to be used in the last CB, applicable only if last CB is present + +} nfapi_nr_dlsch_pdu_t; + +//for csi-rs_pdu: + +//table 3-39 +typedef struct +{ +uint16_t bwp_size;// +uint16_t bwp_start;// +uint8_t subcarrier_spacing;// +uint8_t cyclic_prefix;// +uint16_t start_rb; +uint16_t nr_of_rbs; +uint8_t csi_type;//Value: 0:TRS 1:CSI-RS NZP 2:CSI-RS ZP +uint8_t row;//Row entry into the CSI Resource location table. [TS38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1] Value: 1-18 +uint16_t freq_domain;//Value: Up to the 12 LSBs, actual size is determined by the Row parameter +uint8_t symb_l0;//The time domain location l0 and firstOFDMSymbolInTimeDomain Value: 0->13 +uint8_t symb_l1;// +uint8_t cdm_type; +uint8_t freq_density;//The density field, p and comb offset (for dot5).0: dot5 (even RB), 1: dot5 (odd RB), 2: one, 3: three +uint16_t scramb_id;//ScramblingID of the CSI-RS [TS38.214, sec 5.2.2.3.1] Value: 0->1023 +//tx power info +uint8_t power_control_offset;//Ratio of PDSCH EPRE to NZP CSI-RSEPRE Value :0->23 representing -8 to 15 dB in 1dB steps +uint8_t power_control_offset_ss;//Ratio of SSB/PBCH block EPRE to NZP CSI-RS EPRES 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB + +} nfapi_nr_csi_rs_pdu_t; + +//for ssb_pdu: + +typedef struct +{ + uint32_t bch_payload;//BCH payload. The valid bits are indicated in the PARAM/CONFIG TLVs. If PARAM/CONFIG TLVs indicate MAC generates full bchPayload then the payload length is 31 bits with the 8 LSB bits being. Otherwise timing PBCH bits are generated by the PHY. And for bchPayload the 24 LSB are used. + +} nfapi_nr_mac_generated_mib_pdu_t; + +typedef struct +{ + uint8_t dmrs_type_a_position;//The position of the first DM-RS for downlink and uplink. + uint8_t pdcch_config_sib1;//The parameter PDCCH-ConfigSIB1 that determines a common ControlResourceSet (CORESET) a common search space and necessary PDCCH parameters. + uint8_t cell_barred;//The flag to indicate whether the cell is barred + uint8_t intra_freq_reselection;//The flag to controls cell selection/reselection to intrafrequency cells when the highest ranked cell is barred, or treated as barred by the UE. value 0 1 + +} nfapi_nr_phy_generated_mib_pdu_t; + + +typedef struct +{ + nfapi_nr_mac_generated_mib_pdu_t* mac_generated_mib_pdu; + nfapi_nr_phy_generated_mib_pdu_t* phy_generated_mib_pdu; + +} nfapi_nr_bch_payload_t; + +typedef struct +{ + uint16_t phys_cell_id;//0~1007 + uint8_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block 0 = 0dB 1 = 3dB + uint8_t ssb_block_index;//SS/PBCH block index within a SSB burst set. Required for PBCH DMRS scrambling. Value: 0->63 (Lmax) + uint8_t ssb_subcarrier_offset;// + uint16_t ssb_offset_point_a;//Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Value: 0->2199 + uint8_t bch_payload_flag;//A value indicating how the BCH payload is generated. This should match the PARAM/CONFIG TLVs. Value: 0: MAC generates the full PBCH payload, see Table 3-41, where bchPayload has 31 bits 1: PHY generates the timing PBCH bits, see Table 3-41, where the bchPayload has 24 bits 2: PHY generates the full PBCH payload + nfapi_nr_bch_payload_t bch_payload; + nfapi_nr_tx_precoding_and_beamforming_t precoding_and_beamforming; + +} nfapi_nr_ssb_pdu_t; + +typedef struct +{ + nfapi_nr_pdcch_pdu_t* pdcch_pdu; + nfapi_nr_dlsch_pdu_t* dlsch_pdu;//pdsch_pdu; + nfapi_nr_csi_rs_pdu_t* csi_rs_pdu; + nfapi_nr_ssb_pdu_t* ssb_pdu; +} nfapi_nr_dl_pdu_configuration_t; + +typedef struct +{ + uint16_t pdu_type;//0: PDCCH PDU 1: PDSCH PDU 2: CSI-RS PDU 3: SSB PDU, + uint16_t pdu_size;//Size of the PDU control information (in bytes). This length value includes the 4 bytes required for the PDU type and PDU size parameters. Value 0 -> 65535 + nfapi_nr_dl_pdu_configuration_t* dl_pdu_configuration; + +} nfapi_nr_dl_tti_request_number_of_pdus_t; + +typedef struct +{ + uint8_t pdu_idx;//This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 255 + +} nfapi_nr_dl_tti_request_number_of_ue_t; + +typedef struct +{ + uint8_t n_ue;//Number of UE in this group For SU-MIMO, one group includes one UE only. For MU-MIMO, one group includes up to 12 UEs. Value 1 -> 12 + nfapi_nr_dl_tti_request_number_of_ue_t* ue_list; + +} nfapi_nr_dl_tti_request_number_of_groups_t; + +//3.4.2 dl_tti_request +typedef struct { + uint16_t sfn; //0->1023 + uint16_t slot;//0->319 + uint8_t n_pdus;//Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255 + uint8_t n_group;//Number of UE Groups included in this message. Value 0 -> 255 + nfapi_nr_dl_tti_request_number_of_pdus_t* pdus_list; + nfapi_nr_dl_tti_request_number_of_groups_t* groups_list; + +} nfapi_nr_dl_tti_request_t; + +// Section 3.4.3 ul_tti_request + +//for prach_pdu: +typedef struct +{ + nfapi_nr_dig_bf_interface_t* dig_bf_interface_list; + +} nfapi_nr_ul_beamforming_number_of_prgs_t; + +typedef struct +{ + uint16_t num_prgs; + uint16_t prg_size; + //watchout: dig_bf_interface here, in table 3-43 it's dig_bf_interfaces + uint8_t dig_bf_interface; + nfapi_nr_ul_beamforming_number_of_prgs_t* prgs_list;// + +} nfapi_nr_ul_beamforming_t; + +typedef struct +{ + uint16_t phys_cell_id; + uint8_t num_prach_ocas; + uint8_t prach_format; + uint8_t num_ra; + uint8_t prach_start_symbol; + uint16_t num_cs;// + nfapi_nr_ul_beamforming_t beamforming; + +} nfapi_nr_prach_pdu_t; + +//for pusch_pdu: + + //for nfapi_nr_pusch_data_t; +typedef struct +{ + uint8_t rv_index; + uint8_t harq_process_id; + uint8_t new_data_indicator; + uint32_t tb_size; + uint16_t num_cb; + uint8_t cb_present_and_position[(NFAPI_MAX_NUM_CB+7) / 8]; + +} nfapi_nr_pusch_data_t; + //for nfapi_nr_pusch_uci_t +typedef struct +{ + uint16_t harq_ack_bit_length; + uint16_t csi_part1_bit_length; + uint16_t csi_part2_bit_length; + uint8_t alpha_scaling; + uint8_t beta_offset_harq_ack; + uint8_t beta_offset_csi1; + uint8_t beta_offset_csi2; + +} nfapi_nr_pusch_uci_t; + + //for nfapi_nr_pusch_ptrs_t +typedef struct +{ + uint16_t ptrs_port_index;//PT-RS antenna ports [TS38.214, sec6.2.3.1 and 38.212, section 7.3.1.1.2] Bitmap occupying the 12 LSBs with: bit 0: antenna port 0 bit 11: antenna port 11 and for each bit 0: PTRS port not used 1: PTRS port used + uint8_t ptrs_dmrs_port;//DMRS port corresponding to PTRS. + uint8_t ptrs_re_offset;//PT-RS resource element offset value taken from 0~11 +} nfapi_nr_ptrs_ports_t; + +typedef struct +{ + uint8_t num_ptrs_ports; + nfapi_nr_ptrs_ports_t* ptrs_ports_list; + uint8_t ptrs_time_density; + uint8_t ptrs_freq_density; + uint8_t ul_ptrs_power; + +}nfapi_nr_pusch_ptrs_t; + + //for nfapi_nr_dfts_ofdm_t +typedef struct +{ + uint8_t low_papr_group_number;//Group number for Low PAPR sequence generation. + uint16_t low_papr_sequence_number;//[TS38.211, sec 5.2.2] For DFT-S-OFDM. + uint8_t ul_ptrs_sample_density;//Number of PTRS groups [But I suppose this sentence is misplaced, so as the next one. --Chenyu] + uint8_t ul_ptrs_time_density_transform_precoding;//Number of samples per PTRS group + +} nfapi_nr_dfts_ofdm_t; + +#define PUSCH_PDU_BITMAP_PUSCH_DATA 0x1 +#define PUSCH_PDU_BITMAP_PUSCH_UCI 0x2 +#define PUSCH_PDU_BITMAP_PUSCH_PTRS 0x4 +#define PUSCH_PDU_BITMAP_DFTS_OFDM 0x8 + +typedef struct +{ + uint16_t pdu_bit_map;//Bitmap indicating presence of optional PDUs (see above) + uint16_t rnti; + uint32_t handle;//An opaque handling returned in the RxData.indication and/or UCI.indication message + //BWP + uint16_t bwp_size; + uint16_t bwp_start; + uint8_t subcarrier_spacing; + uint8_t cyclic_prefix; + //pusch information always include + uint16_t target_code_rate; + uint8_t qam_mod_order; + uint8_t mcs_index; + uint8_t mcs_table; + uint8_t transform_precoding; + uint16_t data_scrambling_id; + uint8_t nrOfLayers; + //DMRS + uint8_t ul_dmrs_symb_pos; + uint8_t dmrs_config_type; + uint16_t ul_dmrs_scrambling_id; + uint8_t scid;// + uint8_t num_dmrs_cdm_grps_no_data; + uint16_t dmrs_ports;//DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used + //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] + uint8_t resource_alloc; + uint8_t rb_bitmap[36];// + uint16_t rb_start; + uint16_t rb_size; + uint8_t vrb_to_prb_mapping; + uint8_t frequency_hopping; + uint16_t tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] + uint8_t uplink_frequency_shift_7p5khz; + //Resource Allocation in time domain + uint8_t start_symbol_index; + uint8_t nr_of_symbols; + //Optional Data only included if indicated in pduBitmap + nfapi_nr_pusch_data_t pusch_data; + nfapi_nr_pusch_uci_t pusch_uci; + nfapi_nr_pusch_ptrs_t pusch_ptrs; + nfapi_nr_dfts_ofdm_t dfts_ofdm; + //beamforming + nfapi_nr_ul_beamforming_t beamforming; + +} nfapi_nr_pusch_pdu_t; + +//for pucch_pdu: +typedef struct +{ + uint16_t rnti; + uint32_t handle; + //BWP + uint16_t bwp_size; + uint16_t bwp_start; + uint8_t subcarrier_spacing; + uint8_t cyclic_prefix; + + uint8_t format_type; + uint8_t multi_slot_tx_indicator; + uint8_t pi_2bpsk; + //pucch allocation in freq domain + uint16_t prb_start; + uint16_t prb_size; + //pucch allocation in tome domain + uint8_t start_symbol_index; + uint8_t nr_of_symbols; + //hopping info + uint8_t freq_hop_flag; + uint16_t second_hop_prb; + uint8_t group_hop_flag; + uint8_t sequence_hop_flag; + uint16_t hopping_id; + uint16_t initial_cyclic_shift; + + uint16_t data_scrambling_id; + uint8_t time_domain_occ_idx; + uint8_t pre_dft_occ_idx; + uint8_t pre_dft_occ_len; + //DMRS + uint8_t add_dmrs_flag; + uint16_t dmrs_scrambling_id; + uint8_t dmrs_cyclic_shift; + + uint8_t sr_flag; + uint8_t bit_len_harq; + uint16_t bit_len_csi_part1; + uint16_t bit_len_csi_part2; + + nfapi_nr_ul_beamforming_t beamforming; + +} nfapi_nr_pucch_pdu_t; + +//for srs_pdu: + +typedef struct +{ + uint16_t rnti;//UE RNTI + uint32_t handle;//An opaque handling returned in the SRS.indication + //BWP + uint16_t bwp_size; + uint16_t bwp_start; + uint8_t subcarrier_spacing; + uint8_t cyclic_prefix; + + uint8_t num_ant_ports; + uint8_t num_symbols; + uint8_t num_repetitions; + uint8_t time_start_position;//Starting position in the time domain l0; Note: the MAC undertakes the translation from startPosition to 𝑙0 + uint8_t config_index; + uint16_t sequence_id; + uint8_t bandwidth_index; + uint8_t comb_size; + uint8_t comb_offset;//Transmission comb offset π‘˜ Μ„ TC [TS38.211, Sec 6.4.1.4.3] Value: 0 β†’ 1 (combSize = 0) Value: 0 β†’ 3 (combSize = 1) + uint8_t cyclic_shift; + uint8_t frequency_position; + uint8_t frequency_shift; + uint8_t frequency_hopping; + uint8_t group_or_sequence_hopping;//Group or sequence hopping configuration (RRC parameter groupOrSequenceHopping in SRS-Resource + uint8_t resource_type;//Type of SRS resource allocation + uint16_t t_srs;//SRS-Periodicity in slots [TS38.211 Sec 6.4.1.4.4] Value: 1,2,3,4,5,8,10,16,20,32,40,64,80,160,320,640,1280,2560 + uint16_t t_offset;//Slot offset value [TS38.211, Sec 6.4.1.4.3] Value:0->2559 + + nfapi_nr_ul_beamforming_t beamforming; + +} nfapi_nr_srs_pdu_t; + +// + +typedef enum { + NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE=0, + NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE, + NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE, + NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE, +} nfapi_nr_ul_config_pdu_type_e; + +typedef struct +{ + uint16_t pdu_type;//0: PRACH PDU, 1: PUSCH PDU, 2: PUCCH PDU, 3: SRS PDU + uint16_t pdu_size;//Value: 0 -> 65535 + union + { + nfapi_nr_prach_pdu_t prach_pdu; + nfapi_nr_pusch_pdu_t pusch_pdu; + nfapi_nr_pucch_pdu_t pucch_pdu; + nfapi_nr_srs_pdu_t srs_pdu; + }; + +} nfapi_nr_ul_tti_request_number_of_pdus_t; + +typedef struct +{ + uint8_t pdu_idx;//This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 65535 + +} nfapi_nr_ul_tti_request_number_of_ue_t; + +typedef struct +{ + uint8_t n_ue;//Number of UE in this group For SU-MIMO, one group includes one UE only. For MU-MIMO, one group includes up to 12 UEs. Value 1 -> 6 + nfapi_nr_ul_tti_request_number_of_ue_t ue_list[NFAPI_MAX_NUM_UL_UE_PER_GROUP]; + +} nfapi_nr_ul_tti_request_number_of_groups_t; + +typedef struct { + uint16_t sfn; //0->1023 + uint16_t slot;//0->319 + uint8_t n_pdus;//Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255 + uint8_t rach_present;//Indicates if a RACH PDU will be included in this message. 0: no RACH in this slot 1: RACH in this slot + uint8_t n_ulsch;//Number of ULSCH PDUs that are included in this message. + uint8_t n_ulcch;//Number of ULCCH PDUs + uint8_t n_group;//Number of UE Groups included in this message. Value 0 -> 8 + nfapi_nr_ul_tti_request_number_of_pdus_t pdus_list[NFAPI_MAX_NUM_UL_PDU]; + nfapi_nr_ul_tti_request_number_of_groups_t groups_list[NFAPI_MAX_NUM_GROUPS]; + +} nfapi_nr_ul_tti_request_t; + +//3.4.4 ul_dci_request + +//table 3-54 + +typedef struct +{ + uint16_t pdu_type;//0: PDCCH PDU + uint16_t pdu_size; + nfapi_nr_dl_pdu_configuration_t* phcch_pdu_configuration; + +} nfapi_nr_ul_dci_request_number_of_pdus_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint8_t num_pdus; + nfapi_nr_ul_dci_request_number_of_pdus_t* pdu_list; + +} nfapi_nr_ul_dci_request_t; + +//3.4.5 slot_errors +typedef enum { + NFAPI_NR_SLOT_UL_TTI_MSG_INVALID_STATE, + NFAPI_NR_SLOT_UL_TTI_SFN_OUT_OF_SYNC, + NFAPI_NR_SLOT_UL_TTI_MSG_BCH_MISSING, + NFAPI_NR_SLOT_UL_TTI_MSG_SLOT_ERR + +} nfapi_nr_slot_errors_ul_tti_e; + +typedef enum { + NFAPI_NR_SLOT_DL_TTI_MSG_INVALID_STATE, + NFAPI_NR_SLOT_DL_TTI_MSG_SLOT_ERR + +} nfapi_nr_slot_errors_dl_tti_e; + +typedef enum { + NFAPI_NR_SLOT_UL_DCI_MSG_INVALID_STATE, + NFAPI_NR_SLOT_UL_DCI_MSG_INVALID_SFN, + NFAPI_NR_SLOT_UL_DCI_MSG_UL_DCI_ERR + +} nfapi_nr_slot_errors_ul_dci_e; + +//3.4.6 tx_data_request + +//table 3-58 + +typedef struct +{ + uint16_t pdu_length; + uint16_t pdu_index; + uint32_t num_tlv; + //! fixme + nfapi_int32_tlv_t* tlvs; //nfapi_int32_tlv_t tlvs[num_tlv] + +} nfapi_nr_pdu_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint16_t number_of_pdus; + nfapi_nr_pdu_t* pdu_list; + +} nfapi_nr_tx_data_request_t; + +typedef enum { + NFAPI_NR_DL_DATA_MSG_INVALID_STATE, + NFAPI_NR_DL_DATA_MSG_INVALID_SFN, + NFAPI_NR_DL_DATA_MSG_TX_ERR + +} nfapi_nr_dl_data_errors_e; + +//section 3.4.7 rx_data_indication + +//table 3-61 + +typedef struct +{ + uint32_t handle; + uint16_t rnti; + uint8_t harq_id; + uint16_t pdu_length; + uint8_t ul_cqi; + uint16_t timing_advance;//Timing advance 𝑇𝐴 measured for the UE [TS 38.213, Section 4.2] NTA_new = NTA_old + (TA βˆ’ 31) β‹… 16 β‹… 64⁄2ΞΌ Value: 0 β†’ 63 0xffff should be set if this field is invalid + uint16_t rssi; + //variable ! fixme + uint32_t pdu; //MAC PDU + +} nfapi_nr_rx_data_pdu_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint16_t number_of_pdus; + nfapi_nr_rx_data_pdu_t* pdu_list; + +} nfapi_nr_rx_data_indication_t; + +//3.4.8 crc_indication +//table 3-62 +typedef struct +{ + uint32_t handle; + uint16_t rnti; + uint8_t harq_id; + uint8_t tb_crc_status; + uint16_t num_cb;//If CBG is not used this parameter can be set to zero. Otherwise the number of CBs in the TB. Value: 0->65535 + //! fixme + uint8_t* cb_crc_status;//cb_crc_status[ceil(NumCb/8)]; + uint8_t ul_cqi; + uint16_t timing_advance; + uint16_t rssi; + +} nfapi_nr_crc_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint16_t number_crcs; + nfapi_nr_crc_t* crc_list; + +} nfapi_nr_crc_indication_t; + +//3.4.9 uci_indication + +//table 3-67 +typedef struct +{ + uint8_t sr_indication; + uint8_t sr_confidence_level; + +} nfapi_nr_sr_pdu_0_1_t; +//table 3-69 +typedef struct +{ + uint16_t sr_bit_len; + //! fixme + uint8_t* sr_payload;//sr_payload[ceil(sr_bit_len/8)]; + +} nfapi_nr_sr_pdu_2_3_4_t; +//table 3-68 +typedef struct +{ + uint8_t harq_value;//Indicates result on HARQ data. Value: 0 = pass 1 = fail 2 = not present + +} nfapi_nr_harq_t; + +//table 3-70 +typedef struct +{ + uint8_t harq_crc; + uint16_t harq_bit_len; + //! fixme + uint8_t* harq_payload;//harq_payload[ceil(harq_bit_len)]; +} nfapi_nr_harq_pdu_2_3_4_t; + +typedef struct +{ + uint8_t num_harq; + uint8_t harq_confidence_level; + nfapi_nr_harq_t* harq_list; + +} nfapi_nr_harq_pdu_0_1_t; + +//table 3-71 +typedef struct +{ + uint8_t csi_part1_crc; + uint16_t csi_part1_bit_len; + //! fixme + uint8_t* csi_part1_payload;//uint8_t[ceil(csiPart1BitLen/8)] + +} nfapi_nr_csi_part1_pdu_t; + +//table 3-72 +typedef struct +{ + uint8_t csi_part2_crc; + uint16_t csi_part2_bit_len; + //! fixme + uint8_t* csi_part2_payload;//uint8_t[ceil(csiPart2BitLen/8)] +} nfapi_nr_csi_part2_pdu_t; + +//table 3-63 + + //for dci_pusch_pdu +typedef struct +{ + uint8_t pdu_bit_map; + uint32_t handle; + uint16_t rnti; + uint8_t ul_cqi; + uint16_t timing_advance; + uint16_t rssi; + nfapi_nr_harq_pdu_2_3_4_t harq;//table 3-70 + nfapi_nr_csi_part1_pdu_t csi_part1;//71 + nfapi_nr_csi_part2_pdu_t csi_part2;//72 + +}nfapi_nr_uci_pusch_pdu_t; + +//for PUCCH PDU Format 0/1 +typedef struct +{ + uint8_t pdu_bit_map; + uint32_t handle; + uint16_t rnti; + uint8_t pucch_format;//PUCCH format Value: 0 -> 1 0: PUCCH Format0 1: PUCCH Format1 + uint8_t ul_cqi; + uint16_t timing_advance; + uint16_t rssi; + nfapi_nr_sr_pdu_0_1_t sr;//67 + nfapi_nr_harq_pdu_0_1_t harq;//68 + + +}nfapi_nr_uci_pucch_pdu_format_0_1_t; + +//PUCCH PDU Format 2/3/4 +typedef struct +{ + uint8_t pdu_bit_map; + uint32_t handle; + uint16_t rnti; + uint8_t pucch_format;//PUCCH format Value: 0 -> 2 0: PUCCH Format2 1: PUCCH Format3 2: PUCCH Format4 + uint8_t ul_cqi; + uint16_t timing_advance; + uint16_t rssi; + nfapi_nr_sr_pdu_2_3_4_t sr;//69 + nfapi_nr_harq_pdu_2_3_4_t harq;//70 + nfapi_nr_csi_part1_pdu_t csi_part1;//71 + nfapi_nr_csi_part2_pdu_t csi_part2;//72 + +}nfapi_nr_uci_pucch_pdu_format_2_3_4_t; + +//for SR, HARQ and CSI Part 1/ 2 PDUs + +typedef struct +{ + nfapi_nr_uci_pusch_pdu_t* pusch_pdu; + nfapi_nr_uci_pucch_pdu_format_0_1_t* pucch_pdu_format_0_1; + nfapi_nr_uci_pucch_pdu_format_2_3_4_t* pucch_pdu_format_2_3_4; + nfapi_nr_sr_pdu_0_1_t* sr_pdu_0_1; + nfapi_nr_sr_pdu_2_3_4_t* sr_pdu_2_3_4; + nfapi_nr_harq_pdu_0_1_t* harq_pdu_0_1; + nfapi_nr_harq_pdu_2_3_4_t* harq_pdu_2_3_4; + nfapi_nr_csi_part1_pdu_t* csi_part1_pdu; + nfapi_nr_csi_part2_pdu_t* csi_part2_pdu; + +} nfapi_nr_uci_pdu_information_t; + +typedef struct +{ + uint16_t pdu_type; + uint16_t pdu_size; + nfapi_nr_uci_pdu_information_t uci_pdu; + +} nfapi_nr_uci_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint16_t num_ucis; + nfapi_nr_uci_t* uci_list; + +} nfapi_nr_uci_indication_t; + +//3.4.10 srs_indication +//table 3-73 + +typedef struct +{ + uint8_t rb_snr; +}nfapi_nr_srs_indication_reported_symbol_resource_block_t; + +typedef struct +{ + uint16_t num_rbs; + nfapi_nr_srs_indication_reported_symbol_resource_block_t* rb_list; +}nfapi_nr_srs_indication_reported_symbol_t; + + +typedef struct +{ + uint32_t handle; + uint16_t rnti; + uint16_t timing_advance; + uint8_t num_symbols; + uint8_t wide_band_snr; + uint8_t num_reported_symbols; + nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list; + +}nfapi_nr_srs_indication_pdu_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint8_t number_of_pdus; + nfapi_nr_srs_indication_pdu_t* pdu_list; + +} nfapi_nr_srs_indication_t; + + +//3.4.11 rach_indication +//table 3-74 +typedef struct +{ + uint8_t preamble_index; + uint16_t timing_advance; + uint32_t preamble_pwr; + +} nfapi_nr_prach_indication_preamble_t; + +typedef struct{ + uint16_t phy_cell_id; + uint8_t symbol_index; + uint8_t slot_index; + uint8_t freq_index; + uint8_t avg_rssi; + uint8_t avg_snr; + uint8_t num_preamble; + nfapi_nr_prach_indication_preamble_t* preamble_list; + +}nfapi_nr_prach_indication_pdu_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint8_t number_of_pdus; + nfapi_nr_prach_indication_pdu_t* pdu_list; + +} nfapi_nr_rach_indication_t; + +#endif diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index 9d6a9775f0..ed8dd3b49a 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -130,9 +130,9 @@ int test_ldpc(short No_iteration, double *modulated_input[MAX_NUM_DLSCH_SEGMENTS]; char *channel_output_fixed[MAX_NUM_DLSCH_SEGMENTS]; unsigned int i,j,trial=0; - short BG=0,Zc,Kb=0,nrows=0;//,ncols; + short BG=0,nrows=0;//,ncols; int no_punctured_columns,removed_bit; - int i1; + int i1,Zc,Kb=0; int R_ind = 0; //Table of possible lifting sizes //short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; @@ -287,7 +287,7 @@ int test_ldpc(short No_iteration, // printf("puncture:%d\n",no_punctured_columns); removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate)); if (ntrials==0) - ldpc_encoder_orig(test_input[0],channel_input[0], block_length, BG, 1); + ldpc_encoder_orig(test_input[0],channel_input[0], Zc, BG, block_length, BG, 1); for (trial=0; trial < ntrials; trial++) { @@ -295,20 +295,20 @@ int test_ldpc(short No_iteration, //// encoder start_meas(&time); for(j=0;j PBCH, 1 --> DCI, -1 --> UCI if (polarMessageType == 0) polar_encoder(testInput, encoderOutput, currentPtr); @@ -278,7 +278,7 @@ if (logFlag){ start_meas(&timeDecoder); if (decoder_int16==1) { - decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, currentPtr); + decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, 0, currentPtr); } else { //0 --> PBCH, 1 --> DCI, -1 --> UCI if (polarMessageType == 0) { decoderState = polar_decoder(channelOutput, diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h index 3e6222c341..540fd3b263 100644 --- a/openair1/PHY/CODING/coding_defs.h +++ b/openair1/PHY/CODING/coding_defs.h @@ -454,14 +454,21 @@ int32_t nr_segmentation(unsigned char *input_buffer, unsigned int *C, unsigned int *K, unsigned int *Zout, - unsigned int *F); + unsigned int *F, + uint8_t BG); -uint32_t nr_compute_tbs(uint8_t mcs, - uint16_t nb_rb, - uint16_t nb_symb_sch, - uint8_t nb_re_dmrs, - uint16_t length_dmrs, - uint8_t Nl); +uint32_t nr_compute_tbs(uint16_t Qm, + uint16_t R, + uint16_t nb_rb, + uint16_t nb_symb_sch, + uint16_t nb_dmrs_prb, + uint16_t nb_rb_oh, + uint8_t Nl); + +uint32_t nr_compute_tbslbrm(uint16_t table, + uint16_t nb_rb, + uint8_t Nl, + uint8_t C); void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f); diff --git a/openair1/PHY/CODING/nrLDPC_encoder/defs.h b/openair1/PHY/CODING/nrLDPC_encoder/defs.h index 4230056f31..85cb852fe5 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/defs.h +++ b/openair1/PHY/CODING/nrLDPC_encoder/defs.h @@ -36,12 +36,12 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh /*ldpc_encoder2.c*/ void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb); -int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); -int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); -int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); +int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); +int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); +int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput); /*ldpc_generate_coefficient.c*/ -int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length,short BG,unsigned char gen_code); +int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,unsigned char gen_code); /* int encode_parity_check_part(unsigned char *c,unsigned char *d, short BG,short Zc,short Kb); diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c index a225730845..6ded22d8ca 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c @@ -46,7 +46,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh short *Gen_shift_values=choose_generator_matrix(BG,Zc); short *no_shift_values, *pointer_shift_values; int no_punctured_columns; - short nrows,ncols; + short nrows,ncols,rate=3; int i1,i2,i3,i4,i5,temp_prime; unsigned char channel_temp,temp; @@ -56,6 +56,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh pointer_shift_values=(short *) pointer_shift_values_BG1; nrows=46; //parity check bits ncols=22; //info bits + rate=3; } else if (BG==2) { @@ -63,6 +64,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh pointer_shift_values=(short *) pointer_shift_values_BG2; nrows=42; //parity check bits ncols=10; //info bits + rate=5; } else { printf("problem with BG\n"); @@ -70,7 +72,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh } - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; //printf("no_punctured_columns = %d\n",no_punctured_columns); diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c index 4c50df2636..fb516549ed 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c @@ -198,16 +198,13 @@ void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,sho } -int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) +int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) { - short Zc,Kb=0,nrows=0,ncols=0; - int i,i1; + short nrows=0,ncols=0; + int i,i1,rate=3; int no_punctured_columns,removed_bit; - //Table of possible lifting sizes - short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; - int simd_size; //determine number of bits in codeword @@ -215,9 +212,9 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh if (BG==1) { //BG=1; - Kb = 22; nrows=46; //parity check bits ncols=22; //info bits + rate=3; } //else if (block_length<=3840) else if (BG==2) @@ -225,29 +222,10 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh //BG=2; nrows=42; //parity check bits ncols=10; // info bits + rate=5; - if (block_length>640) - Kb = 10; - else if (block_length>560) - Kb = 9; - else if (block_length>192) - Kb = 8; - else - Kb = 6; } - //find minimum value in all sets of lifting size - Zc=0; - for (i1=0; i1 < 51; i1++) - { - if (lift_size[i1] >= (double) block_length/Kb) - { - Zc = lift_size[i1]; - //printf("%d\n",Zc); - break; - } - } - AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length); #ifdef DEBUG_LDPC LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d\n",BG,Zc,Kb,block_length); @@ -263,8 +241,8 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3); + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); // printf("%d\n",no_punctured_columns); // printf("%d\n",removed_bit); // unpack input @@ -317,14 +295,12 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh return 0; } -int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) +int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) { - short Zc,Kb=0,nrows=0,ncols=0; - int i,i1,j; + short nrows=0,ncols=0; + int i,i1,j,rate=3; int no_punctured_columns,removed_bit; - //Table of possible lifting sizes - short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; char temp; int simd_size; @@ -350,10 +326,9 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i //if (block_length>3840) if (BG==1) { - //BG=1; - Kb = 22; nrows=46; //parity check bits ncols=22; //info bits + rate=3; } //else if (block_length<=3840) else if (BG==2) @@ -361,28 +336,9 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i //BG=2; nrows=42; //parity check bits ncols=10; // info bits - - if (block_length>640) - Kb = 10; - else if (block_length>560) - Kb = 9; - else if (block_length>192) - Kb = 8; - else - Kb = 6; - } + rate=5; - //find minimum value in all sets of lifting size - Zc=0; - for (i1=0; i1 < 51; i1++) - { - if (lift_size[i1] >= (double) block_length/Kb) - { - Zc = lift_size[i1]; - //printf("%d\n",Zc); - break; - } - } + } #ifdef DEBUG_LDPC LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments); @@ -400,8 +356,8 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3); + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); // printf("%d\n",no_punctured_columns); // printf("%d\n",removed_bit); // unpack input @@ -517,14 +473,13 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i return 0; } -int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) +int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) { - short Zc,Kb=0,nrows=0,ncols=0; - int i,i1,j; + short nrows=0,ncols=0; + int i,i1,j,rate=3; int no_punctured_columns,removed_bit; //Table of possible lifting sizes - short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; char temp; int simd_size; int macro_segment, macro_segment_end; @@ -556,38 +511,16 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha //determine number of bits in codeword if (BG==1) { - BG=1; - Kb = 22; nrows=46; //parity check bits ncols=22; //info bits + rate=3; } else if (BG==2) { - BG=2; nrows=42; //parity check bits ncols=10; // info bits - - if (block_length>640) - Kb = 10; - else if (block_length>560) - Kb = 9; - else if (block_length>192) - Kb = 8; - else - Kb = 6; - } - - //find minimum value in all sets of lifting size - Zc=0; - for (i1=0; i1 < 51; i1++) - { - if (lift_size[i1] >= (double) block_length/Kb) - { - Zc = lift_size[i1]; - //printf("%d\n",Zc); - break; + rate=5; } - } #ifdef DEBUG_LDPC LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments); @@ -605,10 +538,10 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3); - // printf("%d\n",no_punctured_columns); - // printf("%d\n",removed_bit); + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); + //printf("%d\n",no_punctured_columns); + //printf("%d\n",removed_bit); // unpack input memset(c,0,sizeof(unsigned char) * ncols * Zc); memset(d,0,sizeof(unsigned char) * nrows * Zc); diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c index faac021088..5da223dc64 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c @@ -361,24 +361,19 @@ short *choose_generator_matrix(short BG,short Zc) return Gen_shift_values; } -int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length, short BG,unsigned char gen_code) +int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length, short BG,unsigned char gen_code) { unsigned char c[22*384]; //padded input, unpacked, max size unsigned char d[68*384]; //coded output, unpacked, max size unsigned char channel_temp,temp; short *Gen_shift_values, *no_shift_values, *pointer_shift_values; - short Zc; - //initialize for BG == 1 - short Kb = 22; + short nrows = 46;//parity check bits short ncols = 22;//info bits int i,i1,i2,i3,i4,i5,temp_prime,var; - int no_punctured_columns,removed_bit; - //Table of possible lifting sizes - short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; - + int no_punctured_columns,removed_bit,rate=3; int nind=0; int indlist[1000]; int indlist2[1000]; @@ -387,10 +382,9 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho //if (block_length>3840) if (BG==1) { - //BG=1; - Kb = 22; nrows=46; //parity check bits ncols=22; //info bits + rate=3; } //else if (block_length<=3840) else if (BG==2) @@ -398,33 +392,9 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho //BG=2; nrows=42; //parity check bits ncols=10; // info bits - - if (block_length>640) - Kb = 10; - else if (block_length>560) - Kb = 9; - else if (block_length>192) - Kb = 8; - else - Kb = 6; + rate=5; } - //find minimum value in all sets of lifting size - Zc=0; - for (i1=0; i1 < 51; i1++) - { - if (lift_size[i1] >= (double) block_length/Kb) - { - Zc = lift_size[i1]; - //printf("%d\n",Zc); - break; - } - } - if (Zc==0) { - printf("ldpc_encoder_orig: could not determine lifting size\n"); - return(-1); - } - Gen_shift_values=choose_generator_matrix(BG,Zc); if (Gen_shift_values==NULL) { printf("ldpc_encoder_orig: could not find generator matrix\n"); @@ -448,8 +418,8 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho AssertFatal(0,"BG %d is not supported yet\n",BG); } - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*3); + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*rate); //printf("%d\n",no_punctured_columns); //printf("%d\n",removed_bit); // unpack input diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index a847072a4c..7ec530242e 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -601,6 +601,7 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) { uint32_t polar_decoder_int16(int16_t *input, uint64_t *out, + uint8_t ones_flag, const t_nrPolar_params *polarParams) { int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); @@ -650,28 +651,42 @@ uint32_t polar_decoder_int16(int16_t *input, uint64_t Ar = 0; AssertFatal(len<65,"A must be less than 65 bits\n"); + // appending 24 ones before a0 for DCI as stated in 38.212 7.3.2 + uint8_t offset = 0; + if (ones_flag) offset = 3; + if (len<=32) { Ar = (uint32_t)(B[0]>>crclen); - uint8_t A32_flip[4]; + uint8_t A32_flip[4+offset]; + if (ones_flag) { + A32_flip[0] = 0xff; + A32_flip[1] = 0xff; + A32_flip[2] = 0xff; + } uint32_t Aprime= (uint32_t)(Ar<<(32-len)); - A32_flip[0]=((uint8_t *)&Aprime)[3]; - A32_flip[1]=((uint8_t *)&Aprime)[2]; - A32_flip[2]=((uint8_t *)&Aprime)[1]; - A32_flip[3]=((uint8_t *)&Aprime)[0]; - crc = (uint64_t)(crc24c(A32_flip,len)>>8); + A32_flip[0+offset]=((uint8_t *)&Aprime)[3]; + A32_flip[1+offset]=((uint8_t *)&Aprime)[2]; + A32_flip[2+offset]=((uint8_t *)&Aprime)[1]; + A32_flip[3+offset]=((uint8_t *)&Aprime)[0]; + crc = (uint64_t)(crc24c(A32_flip,8*offset+len)>>8); } else if (len<=64) { Ar = (B[0]>>crclen) | (B[1]<<(64-crclen));; - uint8_t A64_flip[8]; - uint64_t Aprime= (uint32_t)(Ar<<(64-len)); - A64_flip[0]=((uint8_t *)&Aprime)[7]; - A64_flip[1]=((uint8_t *)&Aprime)[6]; - A64_flip[2]=((uint8_t *)&Aprime)[5]; - A64_flip[3]=((uint8_t *)&Aprime)[4]; - A64_flip[4]=((uint8_t *)&Aprime)[3]; - A64_flip[5]=((uint8_t *)&Aprime)[2]; - A64_flip[6]=((uint8_t *)&Aprime)[1]; - A64_flip[7]=((uint8_t *)&Aprime)[0]; - crc = (uint64_t)(crc24c(A64_flip,len)>>8); + uint8_t A64_flip[8+offset]; + if (ones_flag) { + A64_flip[0] = 0xff; + A64_flip[1] = 0xff; + A64_flip[2] = 0xff; + } + uint64_t Aprime= (uint64_t)(Ar<<(64-len)); + A64_flip[0+offset]=((uint8_t *)&Aprime)[7]; + A64_flip[1+offset]=((uint8_t *)&Aprime)[6]; + A64_flip[2+offset]=((uint8_t *)&Aprime)[5]; + A64_flip[3+offset]=((uint8_t *)&Aprime)[4]; + A64_flip[4+offset]=((uint8_t *)&Aprime)[3]; + A64_flip[5+offset]=((uint8_t *)&Aprime)[2]; + A64_flip[6+offset]=((uint8_t *)&Aprime)[1]; + A64_flip[7+offset]=((uint8_t *)&Aprime)[0]; + crc = (uint64_t)(crc24c(A64_flip,8*offset+len)>>8); } #if 0 diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 493b43ee74..a130484c8e 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -148,6 +148,7 @@ void polar_encoder_dci(uint32_t *in, void polar_encoder_fast(uint64_t *A, uint32_t *out, int32_t crcmask, + uint8_t ones_flag, t_nrPolar_params *polarParams); int8_t polar_decoder(double *input, @@ -157,6 +158,7 @@ int8_t polar_decoder(double *input, uint32_t polar_decoder_int16(int16_t *input, uint64_t *out, + uint8_t ones_flag, const t_nrPolar_params *polarParams); int8_t polar_decoder_dci(double *input, diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c index df9b53a8b0..8e4b45f744 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c @@ -410,6 +410,7 @@ void build_polar_tables(t_nrPolar_params *polarParams) { void polar_encoder_fast(uint64_t *A, uint32_t *out, int32_t crcmask, + uint8_t ones_flag, t_nrPolar_params *polarParams) { AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K); AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K); @@ -421,6 +422,10 @@ void polar_encoder_fast(uint64_t *A, AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n"); //int bitlen0=bitlen; uint64_t tcrc=0; + uint8_t offset = 0; + + // appending 24 ones before a0 for DCI as stated in 38.212 7.3.2 + if (ones_flag) offset = 3; // A bit string should be stored as 0, 0, ..., 0, a'_0, a'_1, ..., a'_A-1, //???a'_{N-1} a'_{N-2} ... a'_{N-A} 0 .... 0, where N=64,128,192,..., N is smallest multiple of 64 greater than or equal to A @@ -428,38 +433,53 @@ void polar_encoder_fast(uint64_t *A, // First flip A bitstring byte endian for CRC routines (optimized for DLSCH/ULSCH, not PBCH/PDCCH) // CRC reads in each byte in bit positions 7 down to 0, for PBCH/PDCCH we need to read in a_{A-1} down to a_{0}, A = length of bit string (e.g. 32 for PBCH) if (bitlen<=32) { - uint8_t A32_flip[4]; + uint8_t A32_flip[4+offset]; + if (ones_flag) { + A32_flip[0] = 0xff; + A32_flip[1] = 0xff; + A32_flip[2] = 0xff; + } uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen)); - A32_flip[0]=((uint8_t *)&Aprime)[3]; - A32_flip[1]=((uint8_t *)&Aprime)[2]; - A32_flip[2]=((uint8_t *)&Aprime)[1]; - A32_flip[3]=((uint8_t *)&Aprime)[0]; - tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,bitlen)>>8))); + A32_flip[0+offset]=((uint8_t *)&Aprime)[3]; + A32_flip[1+offset]=((uint8_t *)&Aprime)[2]; + A32_flip[2+offset]=((uint8_t *)&Aprime)[1]; + A32_flip[3+offset]=((uint8_t *)&Aprime)[0]; + tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,8*offset+bitlen)>>8))); } else if (bitlen<=64) { - uint8_t A64_flip[8]; - uint64_t Aprime= (uint32_t)(((uint64_t)*A)<<(64-bitlen)); - A64_flip[0]=((uint8_t *)&Aprime)[7]; - A64_flip[1]=((uint8_t *)&Aprime)[6]; - A64_flip[2]=((uint8_t *)&Aprime)[5]; - A64_flip[3]=((uint8_t *)&Aprime)[4]; - A64_flip[4]=((uint8_t *)&Aprime)[3]; - A64_flip[5]=((uint8_t *)&Aprime)[2]; - A64_flip[6]=((uint8_t *)&Aprime)[1]; - A64_flip[7]=((uint8_t *)&Aprime)[0]; - tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,bitlen)>>8))); + uint8_t A64_flip[8+offset]; + if (ones_flag) { + A64_flip[0] = 0xff; + A64_flip[1] = 0xff; + A64_flip[2] = 0xff; + } + uint64_t Aprime= (uint64_t)(((uint64_t)*A)<<(64-bitlen)); + A64_flip[0+offset]=((uint8_t *)&Aprime)[7]; + A64_flip[1+offset]=((uint8_t *)&Aprime)[6]; + A64_flip[2+offset]=((uint8_t *)&Aprime)[5]; + A64_flip[3+offset]=((uint8_t *)&Aprime)[4]; + A64_flip[4+offset]=((uint8_t *)&Aprime)[3]; + A64_flip[5+offset]=((uint8_t *)&Aprime)[2]; + A64_flip[6+offset]=((uint8_t *)&Aprime)[1]; + A64_flip[7+offset]=((uint8_t *)&Aprime)[0]; + tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,8*offset+bitlen)>>8))); } else if (bitlen<=128) { - uint8_t A128_flip[16]; - uint128_t Aprime= (uint32_t)(((uint128_t)*A)<<(128-bitlen)); - A128_flip[0]=((uint8_t*)&Aprime)[15]; A128_flip[1]=((uint8_t*)&Aprime)[14]; - A128_flip[2]=((uint8_t*)&Aprime)[13]; A128_flip[3]=((uint8_t*)&Aprime)[12]; - A128_flip[4]=((uint8_t*)&Aprime)[11]; A128_flip[5]=((uint8_t*)&Aprime)[10]; - A128_flip[6] =((uint8_t*)&Aprime)[9]; A128_flip[7] =((uint8_t*)&Aprime)[8]; - A128_flip[8] =((uint8_t*)&Aprime)[7]; A128_flip[9] =((uint8_t*)&Aprime)[6]; - A128_flip[10]=((uint8_t*)&Aprime)[5]; A128_flip[11]=((uint8_t*)&Aprime)[4]; - A128_flip[12]=((uint8_t*)&Aprime)[3]; A128_flip[13]=((uint8_t*)&Aprime)[2]; - A128_flip[14]=((uint8_t*)&Aprime)[1]; A128_flip[15]=((uint8_t*)&Aprime)[0]; - tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,bitlen)>>8))); + uint8_t A128_flip[16+offset]; + if (ones_flag) { + A128_flip[0] = 0xff; + A128_flip[1] = 0xff; + A128_flip[2] = 0xff; + } + uint128_t Aprime= (uint128_t)(((uint128_t)*A)<<(128-bitlen)); + A128_flip[0+offset]=((uint8_t*)&Aprime)[15]; A128_flip[1+offset]=((uint8_t*)&Aprime)[14]; + A128_flip[2+offset]=((uint8_t*)&Aprime)[13]; A128_flip[3+offset]=((uint8_t*)&Aprime)[12]; + A128_flip[4+offset]=((uint8_t*)&Aprime)[11]; A128_flip[5+offset]=((uint8_t*)&Aprime)[10]; + A128_flip[6+offset] =((uint8_t*)&Aprime)[9]; A128_flip[7+offset] =((uint8_t*)&Aprime)[8]; + A128_flip[8+offset] =((uint8_t*)&Aprime)[7]; A128_flip[9+offset] =((uint8_t*)&Aprime)[6]; + A128_flip[10+offset]=((uint8_t*)&Aprime)[5]; A128_flip[11+offset]=((uint8_t*)&Aprime)[4]; + A128_flip[12+offset]=((uint8_t*)&Aprime)[3]; A128_flip[13+offset]=((uint8_t*)&Aprime)[2]; + A128_flip[14+offset]=((uint8_t*)&Aprime)[1]; A128_flip[15+offset]=((uint8_t*)&Aprime)[0]; + tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,8*offset+bitlen)>>8))); } int n; @@ -473,7 +493,6 @@ void polar_encoder_fast(uint64_t *A, //??? b_{N'-1} b_{N'-2} ... b_{N'-A} b_{N'-A-1} ... b_{N'-A-Nparity} = a_{N-1} a_{N-2} ... a_{N-A} p_{N_parity-1} ... p_0 - for (n=0; ncrcParityBits) | tcrc; else B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits)); diff --git a/openair1/PHY/CODING/nr_compute_tbs.c b/openair1/PHY/CODING/nr_compute_tbs.c index e1c15d4a86..055f697f41 100644 --- a/openair1/PHY/CODING/nr_compute_tbs.c +++ b/openair1/PHY/CODING/nr_compute_tbs.c @@ -24,73 +24,128 @@ author: Hongzhi WANG (TCL) */ #include "PHY/defs_nr_UE.h" -//#include "SCHED/extern.h" - #define INDEX_MAX_TBS_TABLE (93) -//Table 5.1.3.1-1 -uint16_t Mcsindextable1[29][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616}, - {4,658},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}}; + //Table 5.1.2.2-2 uint16_t Tbstable_nr[INDEX_MAX_TBS_TABLE] = {24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,208,224,240,256,272,288,304,320,336,352,368,384,408,432,456,480,504,528,552,576,608,640,672,704,736,768,808,848,888,928,984,1032,1064,1128,1160,1192,1224,1256,1288,1320,1352,1416,1480,1544,1608,1672,1736,1800,1864,1928,2024,2088,2152,2216,2280,2408,2472,2536,2600,2664,2728,2792,2856,2976,3104,3240,3368,3496,3624,3752,3824}; -uint32_t nr_compute_tbs(uint8_t mcs, - uint16_t nb_rb, - uint16_t nb_symb_sch, - uint8_t nb_re_dmrs, - uint16_t length_dmrs, - uint8_t Nl) +uint16_t NPRB_LBRM[7] = {32,66,107,135,162,217,273}; + +uint32_t nr_compute_tbs(uint16_t Qm, + uint16_t R, + uint16_t nb_rb, + uint16_t nb_symb_sch, + uint16_t nb_dmrs_prb, + uint16_t nb_rb_oh, + uint8_t Nl) { - uint16_t nbp_re, nb_re, nb_dmrs_prb, nb_rb_oh,Qm,R; - uint32_t nr_tbs=0; - double Ninfo,Np_info,n,C; - nb_rb_oh = 0; //set to 0 if not configured by higher layer - Qm = Mcsindextable1[mcs][0]; - R = Mcsindextable1[mcs][1]; - nb_dmrs_prb = nb_re_dmrs*length_dmrs; + uint16_t nbp_re, nb_re; + uint32_t nr_tbs=0; + uint32_t Ninfo, Np_info, C; + uint8_t n, scale; - nbp_re = 12 * nb_symb_sch - nb_dmrs_prb - nb_rb_oh; + nbp_re = NR_NB_SC_PER_RB * nb_symb_sch - nb_dmrs_prb - nb_rb_oh; - nb_re = min(156, nbp_re) * nb_rb; + nb_re = min(156, nbp_re) * nb_rb; + + scale = (R>1024)?11:10; // Intermediate number of information bits - Ninfo = (double)((nb_re * R * Qm * Nl)/1024); - - //printf("Ninfo %lf nbp_re %d nb_re %d mcs %d Qm %d, R %d\n", Ninfo, nbp_re, nb_re,mcs, Qm, R); + Ninfo = (nb_re * R * Qm * Nl)>>scale; if (Ninfo <=3824) { - n = max(3, floor(log2(Ninfo)) - 6); - Np_info = max(24, pow(2,n) * floor(Ninfo/pow(2,n))); - + Np_info = max(24, (Ninfo>>n)<= Np_info){ + if (Tbstable_nr[i] >= Np_info){ nr_tbs = Tbstable_nr[i]; break; } } } else { - n = floor(log2(Ninfo-24)) - 5; - Np_info = max(3840, pow(2,n) * round((Ninfo - 24)/pow(2,n))); + n = log2(Ninfo-24)-5; + Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1< 8424){ - C = ceil( (Np_info + 24)/8424 ); - nr_tbs = (uint32_t)(8 * C * ceil( (Np_info + 24)/(8*C) ) - 24); + C = CEILIDIV((Np_info+24),8424); + nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24; } else { - nr_tbs = (uint32_t)(8 * ceil( (Np_info + 24)/8 ) - 24); - //printf("n %lf Np_info %f pow %f ceil %f \n",n, Np_info,pow(2,6),ceil( (Np_info + 24)/8 )); + nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24; } } } + //printf("Ninfo %d nbp_re %d nb_re %d Qm %d, R %d, tbs %d\n", Ninfo, nbp_re, nb_re, Qm, R, nr_tbs); + return nr_tbs; +} - return nr_tbs; + +//tbslbrm calculation according to 5.4.2.1 of 38.212 +uint32_t nr_compute_tbslbrm(uint16_t table, + uint16_t nb_rb, + uint8_t Nl, + uint8_t C) +{ + + uint16_t R, nb_re; + uint16_t nb_rb_lbrm=0; + uint8_t Qm; + int i; + uint32_t nr_tbs=0; + uint32_t Ninfo, Np_info; + uint8_t n; + + for (i=0; i<7; i++) { + if (NPRB_LBRM[i] >= nb_rb){ + nb_rb_lbrm = NPRB_LBRM[i]; + break; + } + } + + Qm = ((table == 1)? 8 : 6); + R = 948; + nb_re = 156 * nb_rb_lbrm; + + // Intermediate number of information bits + Ninfo = (nb_re * R * Qm * Nl)>>10; + + if (Ninfo <=3824) { + n = max(3, floor(log2(Ninfo)) - 6); + Np_info = max(24, (Ninfo>>n)<= Np_info){ + nr_tbs = Tbstable_nr[i]; + break; + } + } + } + else { + n = log2(Ninfo-24)-5; + Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1< 8424){ + nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24; + } + else { + nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24; + } + + } + + } + return nr_tbs; + } diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c index 0954939a58..9d50b4678b 100644 --- a/openair1/PHY/CODING/nr_rate_matching.c +++ b/openair1/PHY/CODING/nr_rate_matching.c @@ -206,3 +206,4 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm, return 0; } + diff --git a/openair1/PHY/CODING/nr_segmentation.c b/openair1/PHY/CODING/nr_segmentation.c index 00616f2189..90586e24d4 100644 --- a/openair1/PHY/CODING/nr_segmentation.c +++ b/openair1/PHY/CODING/nr_segmentation.c @@ -30,25 +30,31 @@ //#define DEBUG_SEGMENTATION int32_t nr_segmentation(unsigned char *input_buffer, - unsigned char **output_buffers, - unsigned int B, - unsigned int *C, - unsigned int *K, - unsigned int *Zout, // [hna] Zout is Zc - unsigned int *F) + unsigned char **output_buffers, + unsigned int B, + unsigned int *C, + unsigned int *K, + unsigned int *Zout, // [hna] Zout is Zc + unsigned int *F, + uint8_t BG) { - unsigned int L,Bprime,Bprime_by_C,Z,r,Kb,k,s,crc,Kprime; + unsigned int L,Bprime,Z,r,Kcb,Kb,k,s,crc,Kprime; - if (B<=8448) { + if (BG==1) + Kcb=8448; + else + Kcb=3840; + + if (B<=Kcb) { L=0; *C=1; Bprime=B; } else { L=24; - *C = B/(8448-L); + *C = B/(Kcb-L); - if ((8448-L)*(*C) < B) + if ((Kcb-L)*(*C) < B) *C=*C+1; Bprime = B+((*C)*L); @@ -63,27 +69,31 @@ int32_t nr_segmentation(unsigned char *input_buffer, } // Find K+ - Bprime_by_C = Bprime/(*C); - if (Bprime <=192) { - Kb = 6; - } else if (Bprime <=560) { - Kb = 8; - } else if (Bprime <=640) { - Kb = 9; - } else if (Bprime <=3840) { - Kb = 10;; - } else { - Kb = 22; + Kprime = Bprime/(*C); + + if (BG==1) + Kb = 22; + else { + if (B > 640) { + Kb = 10; + } else if (B > 560) { + Kb = 9; + } else if (B > 192) { + Kb = 8; + } + else { + Kb = 6; + } } -if ((Bprime_by_C%Kb) > 0) - Z = (Bprime_by_C/Kb)+1; +if ((Kprime%Kb) > 0) + Z = (Kprime/Kb)+1; else - Z = (Bprime_by_C/Kb); + Z = (Kprime/Kb); #ifdef DEBUG_SEGMENTATION - printf("nr segmetation B %u Bprime %u Bprime_by_C %u z %u \n", B, Bprime, Bprime_by_C, Z); + printf("nr segmetation B %u Bprime %u Kprime %u z %u \n", B, Bprime, Kprime, Z); #endif if (Z <= 2) { @@ -128,10 +138,15 @@ else //msg("nr_segmentation.c: Illegal codeword size !!!\n"); return -1; } - *Zout = *K; - *K = *K*Kb; - *F = ((*K) - Bprime_by_C); + *Zout = *K; + + if(BG==1) + *K = *K*22; + else + *K = *K*10; + + *F = ((*K) - Kprime); #ifdef DEBUG_SEGMENTATION printf("final nr seg output Z %u K %u F %u \n", *Zout, *K, *F); @@ -145,7 +160,6 @@ else for (r=0; r<*C; r++) { k = 0; - Kprime = Bprime_by_C; while (k<((Kprime - L)>>3)) { output_buffers[r][k] = input_buffer[s]; @@ -154,6 +168,13 @@ else s++; } + if (*C > 1) { // add CRC + crc = crc24b(output_buffers[r],Kprime-L)>>8; + output_buffers[r][(Kprime-L)>>3] = ((uint8_t*)&crc)[2]; + output_buffers[r][1+((Kprime-L)>>3)] = ((uint8_t*)&crc)[1]; + output_buffers[r][2+((Kprime-L)>>3)] = ((uint8_t*)&crc)[0]; + } + if (*F>0) { for (k=Kprime>>3; k<(*K)>>3; k++) { output_buffers[r][k] = 0; @@ -161,16 +182,10 @@ else } } - if (*C > 1) { // add CRC - crc = crc24b(output_buffers[r],Kprime-L)>>8; - output_buffers[r][(Kprime-L)>>3] = ((uint8_t*)&crc)[2]; - output_buffers[r][1+((Kprime-L)>>3)] = ((uint8_t*)&crc)[1]; - output_buffers[r][2+((Kprime-L)>>3)] = ((uint8_t*)&crc)[0]; - } } } - return 0; + return Kb; } diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index fff1245477..c8df496423 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -484,29 +484,20 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { } } - for (i=0; iulsch[i][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0); - - if (!gNB->ulsch[i][j]) { - LOG_E(PHY,"Can't get gNB ulsch structures\n"); - exit(-1); - } - } - // ULSCH for data - gNB->ulsch[i+1][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0); + gNB->ulsch[i][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0); - if (!gNB->ulsch[i+1][j]) { + if (!gNB->ulsch[i][j]) { LOG_E(PHY,"Can't get gNB ulsch structures\n"); exit(-1); } + /* LOG_I(PHY,"Initializing nFAPI for ULSCH, UE %d\n",i); // [hna] added here for RT implementation uint8_t harq_pid = 0; @@ -521,17 +512,15 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; rel15_ul->ulsch_pdu_rel15.Qm = 2; + rel15_ul->ulsch_pdu_rel15.R = 679; rel15_ul->ulsch_pdu_rel15.mcs = 9; rel15_ul->ulsch_pdu_rel15.rv = 0; rel15_ul->ulsch_pdu_rel15.n_layers = 1; /////////////////////////////////////////////////// + */ - ////////////////////////////////////////////////////////////////////////// } - // this is the transmission mode for the signalling channels - // this will be overwritten with the real transmission mode by the RRC once the UE is connected - //gNB->transmission_mode[i] = fp->nb_antenna_ports_gNB==1 ? 1 : 2; } gNB->dlsch_SI = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg); diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index eb7b62ff99..0c7ce1cdd6 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -877,6 +877,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, pbch_vars[eNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); pbch_vars[eNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); pbch_vars[eNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pbch_vars[eNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); pbch_vars[eNB_id]->llr = (int16_t *)malloc16_clear( 1920 ); // prach_vars[eNB_id]->prachF = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); prach_vars[eNB_id]->prach = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); @@ -888,6 +889,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int idx = (j<<1)+i; pbch_vars[eNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 ); pbch_vars[eNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) ); + pbch_vars[eNB_id]->dl_ch_estimates_time[idx]= (int32_t *)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) ); pbch_vars[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 ); } } diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 3643264c87..57bca9e2ec 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -24,7 +24,7 @@ extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT]; void nr_modulation(uint32_t *in, - uint16_t length, + uint32_t length, uint16_t mod_order, int16_t *out) { diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 228c76c00d..706b4dc113 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -37,7 +37,7 @@ */ void nr_modulation(uint32_t *in, - uint16_t length, + uint32_t length, uint16_t mod_order, int16_t *out); @@ -93,7 +93,6 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, */ void nr_dft(int32_t *z,int32_t *d, uint32_t Msc_PUSCH); - int nr_beam_precoding(int32_t **txdataF, int32_t **txdataF_BF, NR_DL_FRAME_PARMS *frame_parms, diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 0656091c78..89321f637b 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -37,11 +37,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, unsigned short bwp_start_subcarrier, unsigned short nb_rb_pusch) { - int pilot[1320] __attribute__((aligned(16))); + int pilot[3280] __attribute__((aligned(16))); unsigned char aarx; unsigned short k; unsigned int pilot_cnt; - int16_t ch[2],*pil,*rxF,*ul_ch,*fl,*fm,*fr,*fml,*fmr,*fmm; + int16_t ch[2],*pil,*rxF,*ul_ch; + int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh; int ch_offset,symbol_offset, length_dmrs, UE_id = 0; unsigned short n_idDMRS[2] = {0,1}; //to update from pusch config int32_t temp_in_ifft_0[8192*2] __attribute__((aligned(16))); @@ -82,6 +83,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, fmm = filt8_mm0; fml = filt8_m0; fmr = filt8_mr0; + fdcl = filt8_dcl0; + fdcr = filt8_dcr0; + fdclh = filt8_dcl0_h; + fdcrh = filt8_dcr0_h; break; case 1: @@ -91,6 +96,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, fmm = filt8_mm1; fml = filt8_ml1; fmr = filt8_m1; + fdcl = filt8_dcl1; + fdcr = filt8_dcr1; + fdclh = filt8_dcl1_h; + fdcrh = filt8_dcr1_h; break; default: @@ -119,12 +128,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size)); #ifdef DEBUG_PUSCH - printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_DL); + printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_UL); printf("k %d, first_carrier %d\n",k,gNB->frame_parms.first_carrier_offset); printf("rxF addr %p p %d\n", rxF,p); printf("ul_ch addr %p nushift %d\n",ul_ch,nushift); #endif - //if ((gNB->frame_parms.N_RB_DL&1)==0) { + //if ((gNB->frame_parms.N_RB_UL&1)==0) { // Treat first 2 pilots specially (left edge) ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -140,7 +149,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ul_ch, 8); pil+=2; - re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //for (int i= 0; i<8; i++) //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); @@ -156,7 +165,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ul_ch, 8); pil+=2; - re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //printf("ul_ch addr %p\n",ul_ch); @@ -175,7 +184,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); pil+=2; - re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ul_ch+=8; @@ -193,7 +202,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, 8); pil+=2; - re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -206,7 +215,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ul_ch, 8); pil+=2; - re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ul_ch+=8; @@ -227,7 +236,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); pil+=2; - re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -242,7 +251,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, 8); pil+=2; - re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ul_ch+=8; @@ -256,6 +265,69 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ul_ch, 8); + + // check if PRB crosses DC and improve estimates around DC + if ((bwp_start_subcarrier >= gNB->frame_parms.ofdm_symbol_size/2) && (bwp_start_subcarrier+nb_rb_pusch*12 >= gNB->frame_parms.ofdm_symbol_size)) { + ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; + uint16_t idxDC = 2*(gNB->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); + uint16_t idxPil = idxDC/2; + re_offset = k; + pil = (int16_t *)&pilot[0]; + pil += (idxPil-2); + ul_ch += (idxDC-4); + ul_ch = memset(ul_ch, 0, sizeof(int16_t)*10); + re_offset = (re_offset+idxDC/2-2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + // for proper allignment of SIMD vectors + if((gNB->frame_parms.N_RB_UL&1)==0) { + + multadd_real_vector_complex_scalar(fdcl, + ch, + ul_ch-4, + 8); + + pil += 4; + re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + multadd_real_vector_complex_scalar(fdcr, + ch, + ul_ch-4, + 8); + } else { + + multadd_real_vector_complex_scalar(fdclh, + ch, + ul_ch, + 8); + + pil += 4; + re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + multadd_real_vector_complex_scalar(fdcrh, + ch, + ul_ch, + 8); + } + + } +#ifdef DEBUG_PDSCH + ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; + for(uint16_t idxP=0; idxPframe_parms.ofdm_symbol_size*sizeof(int32_t)); memcpy(temp_in_ifft_0, &ul_ch_estimates[aarx][symbol_offset], nb_rb_pusch * NR_NB_SC_PER_RB * sizeof(int32_t)); @@ -322,4 +394,4 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #endif return(0); -} \ No newline at end of file +} diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h index 9b02d2b1af..5c4f218512 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.h +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h @@ -55,7 +55,7 @@ int pseudo_random_sequence(int M_PN, uint32_t *c, uint32_t cinit); void lte_gold_new(LTE_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_table[20][2][14], uint16_t Nid_cell); void generate_dmrs_pbch(uint32_t dmrs_pbch_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE], uint16_t Nid_cell); uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position); -uint16_t get_dmrs_freq_idx_ul(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); +uint16_t get_dmrs_freq_idx_ul(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); #undef EXTERN diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index ad26356abb..9793899dd4 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c +++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c @@ -148,7 +148,7 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue, //printf("x1 : %x, x2 : %x\n",x1,x2); } - for (n=0; n<52; n++) { + for (n=0; n>1) ^ (x1>>4); x1 = x1 ^ (x1<<31) ^ (x1<<28); x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index ab3cf4af9b..06e3948b64 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -130,7 +130,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, } void nr_pdcch_scrambling(uint32_t *in, - uint16_t size, + uint32_t size, uint32_t Nid, uint32_t n_RNTI, uint32_t *out) { @@ -155,23 +155,19 @@ void nr_pdcch_scrambling(uint32_t *in, } } -uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, +uint8_t nr_generate_dci_top(NR_gNB_DCI_ALLOC_t dci_alloc, uint32_t **gold_pdcch_dmrs, int32_t *txdataF, int16_t amp, NR_DL_FRAME_PARMS frame_parms, nfapi_nr_config_request_t config) { int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1]; // 3 for the max coreset duration - uint32_t dmrs_seq[NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD]; - uint16_t dmrs_offset=0; uint16_t cset_start_sc; uint8_t cset_start_symb, cset_nsymb; int k,l,k_prime,dci_idx, dmrs_idx; nr_cce_t cce; nr_reg_t reg; nr_reg_t reg_mapping_list[NR_MAX_PDCCH_AGG_LEVEL*NR_NB_REG_PER_CCE]; - /*First iteration: single DCI*/ - NR_gNB_DCI_ALLOC_t dci_alloc = pdcch_vars.dci_alloc[0]; nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc.pdcch_params; /*The coreset is initialised @@ -189,45 +185,20 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, dci_idx = 0; LOG_D(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb); // DMRS length is per OFDM symbol - uint16_t dmrs_length = (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS)? + uint32_t dmrs_length = (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS)? (pdcch_params.n_rb*6) : (dci_alloc.L*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE) - uint16_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE) + uint32_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE) LOG_D(PHY, "DMRS length per symbol %d\t DCI encoded length %d\n", dmrs_length, encoded_length); + dmrs_length += pdcch_params.rb_offset*6; // To accommodate more DMRS symbols in case of rb offset /// DMRS QPSK modulation - /*There is a need to shift from which index the pregenerated DMRS sequence is used - * see 38211 r15.2.0 section 7.4.1.3.2: assumption is the reference point for k refers to the DMRS sequence*/ - if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) { - for (int symb=cset_start_symb; symb>5; - - dmrs_offset = (pdcch_params.rb_offset*3)&0x1f; - LOG_D(PHY, "PDCCH DMRS offset %d\n", dmrs_offset); - } - for (int symb=cset_start_symb; symb>5)] |= ((gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]>>((i+dmrs_offset)&0x1f))&1)<<(i&0x1f); -#ifdef DEBUG_PDCCH_DMRS - //printf("out 0x%08x in 0x%08x \n", dmrs_seq[(i>>5)], gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]); -#endif - } - - nr_modulation(dmrs_seq, dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated - } else - nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated + + nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated #ifdef DEBUG_PDCCH_DMRS for (int i=0; i>1; i++) - if (dmrs_offset) - printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i, dmrs_seq[i>>5], - mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] ); - else printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i, gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] ); @@ -241,7 +212,7 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value; t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L); - polar_encoder_fast(dci_alloc.dci_pdu, encoder_output, pdcch_params.rnti,currentPtr); + polar_encoder_fast(dci_alloc.dci_pdu, encoder_output, pdcch_params.rnti, 1, currentPtr); #ifdef DEBUG_CHANNEL_CODING printf("polar rnti %d\n",pdcch_params.rnti); printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n", @@ -278,32 +249,28 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, cset_start_sc -= frame_parms.ofdm_symbol_size; /*Reorder REG list for a freq first mapping*/ - uint8_t symb_idx[NR_MAX_CSET_DURATION] = {0,0,0}; uint8_t nb_regs = dci_alloc.L*NR_NB_REG_PER_CCE; - uint8_t regs_per_symb = nb_regs/cset_nsymb; for (int cce_idx=0; cce_idxnb_mod_symbols; uint8_t Qm = rel15->modulation_order; - uint16_t encoded_length = nb_symbols*Qm; + uint32_t encoded_length = nb_symbols*Qm; /// CRC, coding, interleaving and rate matching @@ -122,11 +122,12 @@ printf("\n"); pdcch_params.scrambling_id : config->sch_config.physical_cell_id.value; for (int q=0; qnb_codewords; q++) nr_pdsch_codeword_scrambling(harq->f, - encoded_length, - q, - Nid, - n_RNTI, - scrambled_output[q]); + encoded_length, + q, + Nid, + n_RNTI, + scrambled_output[q]); + stop_meas(dlsch_scrambling_stats); #ifdef DEBUG_DLSCH printf("PDSCH scrambling:\n"); @@ -176,7 +177,7 @@ for (int l=0; lnb_layers; l++) //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007 /// DMRS QPSK modulation - uint16_t n_dmrs = (rel15->n_prb*rel15->nb_re_dmrs)<<1; + uint16_t n_dmrs = ((rel15->n_prb+rel15->start_prb)*rel15->nb_re_dmrs)<<1; int16_t mod_dmrs[n_dmrs<<1]; uint8_t dmrs_type = config->pdsch_config.dmrs_type.value; uint8_t mapping_type = config->pdsch_config.mapping_type.value; @@ -221,6 +222,10 @@ ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol); uint8_t k_prime=0; uint16_t m=0, n=0, dmrs_idx=0, k=0; int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP; + if (dmrs_type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k) + dmrs_idx = rel15->start_prb*6; + else + dmrs_idx = rel15->start_prb*4; for (int l=rel15->start_symbol; lstart_symbol+rel15->nb_symbols; l++) { k = start_sc; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h index 3419be30fa..d982a17ea7 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h @@ -54,11 +54,11 @@ void nr_get_rbg_list(uint32_t bitmap, uint8_t n_rbg, uint8_t* rbg_list); void nr_get_PRG_parms(NR_BWP_PARMS* bwp, NR_gNB_DCI_ALLOC_t dci_alloc, uint8_t prb_bundling_type); void nr_pdsch_codeword_scrambling(uint8_t *in, - uint16_t size, - uint8_t q, - uint32_t Nid, - uint32_t n_RNTI, - uint32_t* out); + uint32_t size, + uint8_t q, + uint32_t Nid, + uint32_t n_RNTI, + uint32_t* out); void nr_fill_dlsch(PHY_VARS_gNB *gNB, int frame, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 14371e89e2..d001141f37 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -283,18 +283,21 @@ int nr_dlsch_encoding(unsigned char *a, nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; uint16_t nb_rb = rel15.n_prb; uint8_t nb_symb_sch = rel15.nb_symbols; - uint32_t A, Z, F=0; - uint32_t *pz = &Z; + uint32_t A, Z, Kb, F=0; + uint32_t *Zc = &Z; uint8_t mod_order = rel15.modulation_order; - uint16_t Kr=0,r,r_offset=0; + uint16_t Kr=0,r; + uint32_t r_offset=0; //uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS]; uint8_t BG=1; uint32_t E; - uint8_t Ilbrm = 0; + uint8_t Ilbrm = 1; uint32_t Tbslbrm = 950984; //max tbs uint8_t nb_re_dmrs = rel15.nb_re_dmrs; + uint16_t R=rel15.coding_rate; uint16_t length_dmrs = 1; float Coderate = 0.0; + uint8_t Nl = 4; /* uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS]; //unsigned char @@ -310,9 +313,6 @@ int nr_dlsch_encoding(unsigned char *a, G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15.nb_layers); LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order); - - - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, rel15.nb_layers); // if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet @@ -326,38 +326,58 @@ int nr_dlsch_encoding(unsigned char *a, printf("%02x.",a[i]); printf("\n"); */ - // Add 24-bit crc (polynomial A) to payload - crc = crc24a(a,A)>>8; - a[A>>3] = ((uint8_t*)&crc)[2]; - a[1+(A>>3)] = ((uint8_t*)&crc)[1]; - a[2+(A>>3)] = ((uint8_t*)&crc)[0]; - //printf("CRC %x (A %d)\n",crc,A); - //printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]); - dlsch->harq_processes[harq_pid]->B = A+24; - // dlsch->harq_processes[harq_pid]->b = a; + if (A > 3824) { + // Add 24-bit crc (polynomial A) to payload + crc = crc24a(a,A)>>8; + a[A>>3] = ((uint8_t*)&crc)[2]; + a[1+(A>>3)] = ((uint8_t*)&crc)[1]; + a[2+(A>>3)] = ((uint8_t*)&crc)[0]; + //printf("CRC %x (A %d)\n",crc,A); + //printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]); + + dlsch->harq_processes[harq_pid]->B = A+24; + // dlsch->harq_processes[harq_pid]->b = a; - AssertFatal((A/8)+4 <= MAX_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_DLSCH_PAYLOAD_BYTES); + AssertFatal((A/8)+4 <= MAX_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_DLSCH_PAYLOAD_BYTES); - memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); + memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); // why is this +4 if the CRC is only 3 bytes? + } + else { + // Add 16-bit crc (polynomial A) to payload + crc = crc16(a,A)>>16; + a[A>>3] = ((uint8_t*)&crc)[1]; + a[1+(A>>3)] = ((uint8_t*)&crc)[0]; + //printf("CRC %x (A %d)\n",crc,A); + //printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]); + + dlsch->harq_processes[harq_pid]->B = A+16; + // dlsch->harq_processes[harq_pid]->b = a; + + AssertFatal((A/8)+3 <= MAX_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,MAX_DLSCH_PAYLOAD_BYTES); - nr_segmentation(dlsch->harq_processes[harq_pid]->b, - dlsch->harq_processes[harq_pid]->c, - dlsch->harq_processes[harq_pid]->B, - &dlsch->harq_processes[harq_pid]->C, - &dlsch->harq_processes[harq_pid]->K, - pz, // [hna] pz is Zc - &dlsch->harq_processes[harq_pid]->F); + memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+3); // using 3 bytes to mimic the case of 24 bit crc + } + if (R<1000) + Coderate = (float) R /(float) 1024; + else // to scale for mcs 20 and 26 in table 5.1.3.1-2 which are decimal and input 2* in nr_tbs_tools + Coderate = (float) R /(float) 2048; + + if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) + BG = 2; + else + BG = 1; + + Kb = nr_segmentation(dlsch->harq_processes[harq_pid]->b, + dlsch->harq_processes[harq_pid]->c, + dlsch->harq_processes[harq_pid]->B, + &dlsch->harq_processes[harq_pid]->C, + &dlsch->harq_processes[harq_pid]->K, + Zc, + &dlsch->harq_processes[harq_pid]->F, + BG); F = dlsch->harq_processes[harq_pid]->F; - Coderate = (float) A /(float) G; - - if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ - BG = 2; - } - else{ - BG = 1; - } Kr = dlsch->harq_processes[harq_pid]->K; #ifdef DEBUG_DLSCH_CODING @@ -365,7 +385,7 @@ int nr_dlsch_encoding(unsigned char *a, Kr_bytes = Kr>>3; #endif - //printf("segment Z %d k %d Kr %d BG %d\n", *pz,dlsch->harq_processes[harq_pid]->K,Kr,BG); + //printf("segment Z %d k %d Kr %d BG %d C %d\n", *Zc,dlsch->harq_processes[harq_pid]->K,Kr,BG,dlsch->harq_processes[harq_pid]->C); for (r=0; rharq_processes[harq_pid]->C; r++) { //d_tmp[r] = &dlsch->harq_processes[harq_pid]->d[r][0]; @@ -374,32 +394,21 @@ int nr_dlsch_encoding(unsigned char *a, printf("Encoder: B %d F %d \n",dlsch->harq_processes[harq_pid]->B, dlsch->harq_processes[harq_pid]->F); printf("start ldpc encoder segment %d/%d\n",r,dlsch->harq_processes[harq_pid]->C); printf("input %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->c[r][0], dlsch->harq_processes[harq_pid]->c[r][1], dlsch->harq_processes[harq_pid]->c[r][2],dlsch->harq_processes[harq_pid]->c[r][3], dlsch->harq_processes[harq_pid]->c[r][4]); - for (int cnt =0 ; cnt < 22*(*pz)/8; cnt ++){ + for (int cnt =0 ; cnt < 22*(*Zc)/8; cnt ++){ printf("%d ", dlsch->harq_processes[harq_pid]->c[r][cnt]); } printf("\n"); #endif - //ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],Kr,BG,0); - //ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],Kr,BG,NULL,NULL,NULL,NULL); + //ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],*Zc,Kb,Kr,BG,0); + //ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],*Zc,Kb,Kr,BG,NULL,NULL,NULL,NULL); } - //for (int i=0;i<68*384;i++) - // printf("channel_input[%d]=%d\n",i,channel_input[i]); + for(int j=0;j<(dlsch->harq_processes[harq_pid]->C/8+1);j++) { + ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,dlsch->harq_processes[harq_pid]->C,j,NULL,NULL,NULL,NULL); + } - - /*printf("output %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->d[0][0], dlsch->harq_processes[harq_pid]->d[0][1], dlsch->harq_processes[harq_pid]->d[r][2],dlsch->harq_processes[harq_pid]->d[0][3], dlsch->harq_processes[harq_pid]->d[0][4]); - for (int cnt =0 ; cnt < 66*(*pz); cnt ++){ - printf("%d \n", dlsch->harq_processes[harq_pid]->d[0][cnt]); - } - printf("\n");*/ - - //ldpc_encoder_optim_8seg(dlsch->harq_processes[harq_pid]->c,d_tmp,Kr,BG,dlsch->harq_processes[harq_pid]->C,NULL,NULL,NULL,NULL); - ldpc_encoder_optim_8seg(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,Kr,BG,dlsch->harq_processes[harq_pid]->C,NULL,NULL,NULL,NULL); - - //printf("end ldpc encoder -- output\n"); - #ifdef DEBUG_DLSCH_CODING write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4); write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[0][0],(3*8*Kr_bytes)+12,1,4); @@ -409,13 +418,14 @@ int nr_dlsch_encoding(unsigned char *a, for (r=0; rharq_processes[harq_pid]->C; r++) { - if (dlsch->harq_processes[harq_pid]->F>0) { - for (int k=(Kr-F-2*(*pz)); kharq_processes[harq_pid]->d[r][k] = NR_NULL; - //if (k<(Kr-F+8)) - //printf("r %d filler bits [%d] = %d \n", r,k, dlsch->harq_processes[harq_pid]->d[r][k]); - } - } + if (dlsch->harq_processes[harq_pid]->F>0) { + for (int k=(Kr-F-2*(*Zc)); kharq_processes[harq_pid]->d[r][k] = NR_NULL; + //if (k<(Kr-F+8)) + //printf("r %d filler bits [%d] = %d \n", r,k, dlsch->harq_processes[harq_pid]->d[r][k]); + } + } + #ifdef DEBUG_DLSCH_CODING printf("Rate Matching, Code segment %d (coded bits (G) %u, unpunctured/repeated bits per code segment %d, mod_order %d, nb_rb %d)...\n", r, @@ -430,26 +440,31 @@ int nr_dlsch_encoding(unsigned char *a, E = nr_get_E(G, dlsch->harq_processes[harq_pid]->C, mod_order, rel15.nb_layers, r); + // for tbslbrm calculation according to 5.4.2.1 of 38.212 + if (rel15.nb_layers < Nl) + Nl = rel15.nb_layers; + + Tbslbrm = nr_compute_tbslbrm(rel15.mcs_table,nb_rb,Nl,dlsch->harq_processes[harq_pid]->C); + nr_rate_matching_ldpc(Ilbrm, Tbslbrm, BG, - *pz, + *Zc, dlsch->harq_processes[harq_pid]->d[r], dlsch->harq_processes[harq_pid]->e+r_offset, dlsch->harq_processes[harq_pid]->C, rel15.redundancy_version, E); - #ifdef DEBUG_DLSCH_CODING for (int i =0; i<16; i++) printf("output ratematching e[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset); #endif nr_interleaving_ldpc(E, - mod_order, - dlsch->harq_processes[harq_pid]->e+r_offset, - dlsch->harq_processes[harq_pid]->f+r_offset); + mod_order, + dlsch->harq_processes[harq_pid]->e+r_offset, + dlsch->harq_processes[harq_pid]->f+r_offset); #ifdef DEBUG_DLSCH_CODING diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c index ac87a8194b..859e59d055 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c @@ -257,7 +257,7 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { AssertFatal(gNB!=NULL,"gNB is null\n"); for (i=0; idlsch[i]!=NULL,"gNB->dlsch[%d] is null\n",i); - AssertFatal(gNB->dlsch[i]!=NULL,"gNB->dlsch[%d][0] is null\n",i); + AssertFatal(gNB->dlsch[i][0]!=NULL,"gNB->dlsch[%d][0] is null\n",i); LOG_D(PHY,"searching for rnti %x : dlsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->dlsch[i][0]->harq_mask,gNB->dlsch[i][0]->rnti,first_free_index); if ((gNB->dlsch[i][0]->harq_mask >0) && (gNB->dlsch[i][0]->rnti==rnti)) return i; @@ -269,6 +269,26 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { return first_free_index; } +int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { + + uint16_t i; + int16_t first_free_index=-1; + + AssertFatal(gNB!=NULL,"gNB is null\n"); + for (i=0; iulsch[i]!=NULL,"gNB->ulsch[%d] is null\n",i); + AssertFatal(gNB->ulsch[i][0]!=NULL,"gNB->ulsch[%d][0] is null\n",i); + LOG_D(PHY,"searching for rnti %x : ulsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->ulsch[i][0]->harq_mask,gNB->ulsch[i][0]->rnti,first_free_index); + if ((gNB->ulsch[i][0]->harq_mask >0) && + (gNB->ulsch[i][0]->rnti==rnti)) return i; + else if ((gNB->ulsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i; + } + if (type == SEARCH_EXIST) return -1; + if (first_free_index != -1) + gNB->ulsch[first_free_index][0]->rnti = 0; + return first_free_index; +} + void nr_fill_dlsch(PHY_VARS_gNB *gNB, int frame, int slot, @@ -290,3 +310,41 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB, } +void nr_fill_ulsch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_pusch_pdu_t *ulsch_pdu) { + + + int ulsch_id = find_nr_ulsch(ulsch_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE); + AssertFatal( (ulsch_id>=0) && (ulsch_idrnti,ulsch_id); + + NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ulsch_id][0]; + int harq_pid = ulsch_pdu->pusch_data.harq_process_id; + ulsch->rnti = ulsch_pdu->rnti; + //ulsch->rnti_type; + ulsch->harq_mask |= 1<harq_process_id[slot] = harq_pid; + + nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch->harq_processes[harq_pid]->ulsch_pdu; + + LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid); + + + //FK this is still a bad hack. We need to replace the L1 FAPI structures with the new scf ones as well. + rel15_ul->rnti = ulsch_pdu->rnti; + rel15_ul->ulsch_pdu_rel15.start_rb = ulsch_pdu->rb_start; + rel15_ul->ulsch_pdu_rel15.number_rbs = ulsch_pdu->rb_size; + rel15_ul->ulsch_pdu_rel15.start_symbol = ulsch_pdu->start_symbol_index; + rel15_ul->ulsch_pdu_rel15.number_symbols = ulsch_pdu->nr_of_symbols; + rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; //where should this come from? + rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; //where should this come from? + rel15_ul->ulsch_pdu_rel15.Qm = ulsch_pdu->qam_mod_order; + rel15_ul->ulsch_pdu_rel15.mcs = ulsch_pdu->mcs_index; + rel15_ul->ulsch_pdu_rel15.rv = ulsch_pdu->pusch_data.rv_index; + rel15_ul->ulsch_pdu_rel15.n_layers = ulsch_pdu->nrOfLayers; + rel15_ul->ulsch_pdu_rel15.R = ulsch_pdu->target_code_rate; + +} + diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c index bb114fa390..af83c17fc1 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c @@ -298,7 +298,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, a_reversed |= (((uint64_t)pbch->pbch_a_prime>>i)&1)<<(31-i); /// CRC, coding and rate matching - polar_encoder_fast (&a_reversed, (uint32_t *)pbch->pbch_e, 0, + polar_encoder_fast (&a_reversed, (uint32_t *)pbch->pbch_e, 0, 0, nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL) ); #ifdef DEBUG_PBCH_ENCODING diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c index 8d9bf00639..303282929f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c @@ -85,7 +85,7 @@ uint8_t get_delta(uint8_t ap, uint8_t config) { return ((config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][2]):(pdsch_dmrs_2[ap][2])); } -uint16_t get_dmrs_freq_idx(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) { +uint16_t get_dmrs_freq_idx(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) { uint16_t dmrs_idx = (dmrs_type)? (6*n+k_prime+delta):((n<<2)+(k_prime<<1)+delta); return dmrs_idx; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h index 02f454b7d0..6f07874ca0 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h +++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h @@ -45,6 +45,6 @@ void get_Wf(int8_t *Wf, uint8_t ap, uint8_t config); uint8_t get_delta(uint8_t ap, uint8_t config); -uint16_t get_dmrs_freq_idx(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); +uint16_t get_dmrs_freq_idx(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); uint8_t get_l0(uint8_t mapping_type, uint8_t dmrs_typeA_position); diff --git a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c index 07ca17cd6d..10ac17acab 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c @@ -31,32 +31,42 @@ */ #include "nr_transport_common_proto.h" +#include "PHY/CODING/coding_defs.h" -/// Target code rate tables indexed by Imcs -uint16_t nr_target_code_rate_table1[29] = {120, 157, 193, 251, 308, 379, 449, 526, 602, 679, 340, 378, 434, 490, 553, \ - 616, 658, 438, 466, 517, 567, 616, 666, 719, 772, 822, 873, 910, 948}; - // Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point -uint16_t nr_target_code_rate_table2[28] = {120, 193, 308, 449, 602, 378, 434, 490, 553, 616, 658, 466, 517, 567, \ - 616, 666, 719, 772, 822, 873, 1365, 711, 754, 797, 841, 885, 1833, 948}; -uint16_t nr_target_code_rate_table3[29] = {30, 40, 50, 64, 78, 99, 120, 157, 193, 251, 308, 379, 449, 526, 602, 340, \ - 378, 434, 490, 553, 616, 438, 466, 517, 567, 616, 666, 719, 772}; -uint16_t nr_tbs_table[93] = {24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 208, 224, 240, 256, 272, 288, 304, 320, \ - 336, 352, 368, 384, 408, 432, 456, 480, 504, 528, 552, 576, 608, 640, 672, 704, 736, 768, 808, 848, 888, 928, 984, 1032, 1064, 1128, 1160, 1192, 1224, 1256, \ - 1288, 1320, 1352, 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1864, 1928, 2024, 2088, 2152, 2216, 2280, 2408, 2472, 2536, 2600, 2664, 2728, 2792, 2856, 2976, \ - 3104, 3240, 3368, 3496, 3624, 3752, 3824}; +//Table 5.1.3.1-1 of 38.214 +uint16_t Table_51311[29][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616}, + {4,658},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}}; -uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx) { +//Table 5.1.3.1-2 of 38.214 +// Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point +uint16_t Table_51312[28][2] = {{2,120},{2,193},{2,308},{2,449},{2,602},{4,378},{4,434},{4,490},{4,553},{4,616},{4,658},{6,466},{6,517},{6,567},{6,616},{6,666}, + {6,719},{6,772},{6,822},{6,873},{8,1365},{8,711},{8,754},{8,797},{8,841},{8,885},{8,1833},{8,948}}; + +//Table 5.1.3.1-3 of 38.214 +uint16_t Table_51313[29][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{4,340}, + {4,378},{4,434},{4,490},{4,553},{4,616},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666}, {6,719}, {6,772}}; + +//Table 6.1.4.1-1 of 38.214 TODO fix for tp-pi2BPSK +uint16_t Table_61411[28][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616}, + {4,658},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}}; + +//Table 6.1.4.1-2 of 38.214 TODO fix for tp-pi2BPSK +uint16_t Table_61412[28][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679}, + {4,378},{4,434},{4,490},{4,553},{4,616},{4,658},{4,699},{4,772},{6,567},{6,616},{6,666}, {6,772}}; + + +uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) { switch(table_idx) { + case 0: + return (Table_51311[Imcs][0]); + break; + case 1: - return (((Imcs<10)||(Imcs==29))?2:((Imcs<17)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1); + return (Table_51312[Imcs][0]); break; case 2: - return (((Imcs<5)||(Imcs==28))?2:((Imcs<11)||(Imcs==29))?4:((Imcs<20)||(Imcs==30))?6:((Imcs<28)||(Imcs==31))?8:-1); - break; - - case 3: - return (((Imcs<15)||(Imcs==29))?2:((Imcs<21)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1); + return (Table_51313[Imcs][0]); break; default: @@ -64,18 +74,18 @@ uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx) { } } -uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) { +uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) { switch(table_idx) { + case 0: + return (Table_51311[Imcs][1]); + break; + case 1: - return (nr_target_code_rate_table1[Imcs]); + return (Table_51312[Imcs][1]); break; case 2: - return (nr_target_code_rate_table2[Imcs]); - break; - - case 3: - return (nr_target_code_rate_table3[Imcs]); + return (Table_51313[Imcs][1]); break; default: @@ -83,6 +93,60 @@ uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) { } } +uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) { + switch(table_idx) { + case 0: + return (Table_51311[Imcs][0]); + break; + + case 1: + return (Table_51312[Imcs][0]); + break; + + case 2: + return (Table_51313[Imcs][0]); + break; + + case 3: + return (Table_61411[Imcs][0]); + break; + + case 4: + return (Table_61412[Imcs][0]); + break; + + default: + AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx); + } +} + +uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) { + switch(table_idx) { + case 0: + return (Table_51311[Imcs][1]); + break; + + case 1: + return (Table_51312[Imcs][1]); + break; + + case 2: + return (Table_51313[Imcs][1]); + break; + + case 3: + return (Table_61411[Imcs][1]); + break; + + case 4: + return (Table_61412[Imcs][1]); + break; + + default: + AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx); + } +} + static inline uint8_t is_codeword_disabled(uint8_t format, uint8_t Imcs, uint8_t rv) { return ((format==NFAPI_NR_DL_DCI_FORMAT_1_1)&&(Imcs==26)&&(rv==1)); } @@ -103,16 +167,16 @@ static inline uint8_t get_table_idx(uint8_t mcs_table, uint8_t dci_format, uint8 return 1; } -void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, - nfapi_nr_dl_config_dci_dl_pdu dci_pdu, - nfapi_nr_config_request_t config) { +void nr_get_tbs_dl(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, + nfapi_nr_dl_config_dci_dl_pdu dci_pdu, + nfapi_nr_config_request_t config) { LOG_D(MAC, "TBS calculation\n"); nfapi_nr_dl_config_pdcch_parameters_rel15_t params_rel15 = dci_pdu.pdcch_params_rel15; nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_rel15 = &dlsch_pdu->dlsch_pdu_rel15; uint8_t rnti_type = params_rel15.rnti_type; - uint8_t N_PRB_oh = ((rnti_type==NFAPI_NR_RNTI_SI)||(rnti_type==NFAPI_NR_RNTI_RA)||(rnti_type==NFAPI_NR_RNTI_P))? 0 : \ + uint16_t N_PRB_oh = ((rnti_type==NFAPI_NR_RNTI_SI)||(rnti_type==NFAPI_NR_RNTI_RA)||(rnti_type==NFAPI_NR_RNTI_P))? 0 : \ (config.pdsch_config.x_overhead.value); uint8_t N_PRB_DMRS = (config.pdsch_config.dmrs_type.value == NFAPI_NR_DMRS_TYPE1)?6:4; //This only works for antenna port 1000 uint8_t N_sh_symb = dlsch_rel15->nb_symbols; @@ -120,56 +184,35 @@ void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS - N_PRB_oh; LOG_D(MAC, "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n", N_RE_prime, N_sh_symb, N_PRB_DMRS, N_PRB_oh); - uint16_t N_RE, Ninfo, Ninfo_prime, C, TBS=0, R; - uint8_t table_idx, Qm, n, scale; + uint16_t R; + uint32_t TBS=0; + uint8_t table_idx, Qm; /*uint8_t mcs_table = config.pdsch_config.mcs_table.value; uint8_t ss_type = params_rel15.search_space_type; uint8_t dci_format = params_rel15.dci_format; get_table_idx(mcs_table, dci_format, rnti_type, ss_type);*/ - table_idx = 1; - scale = ((table_idx==2)&&((Imcs==20)||(Imcs==26)))?11:10; - - N_RE = min(156, N_RE_prime)*dlsch_rel15->n_prb; - R = nr_get_code_rate(Imcs, table_idx); - Qm = nr_get_Qm(Imcs, table_idx); - Ninfo = (N_RE*R*Qm*dlsch_rel15->nb_layers)>>scale; + table_idx = 0; + R = nr_get_code_rate_dl(Imcs, table_idx); + Qm = nr_get_Qm_dl(Imcs, table_idx); - if (Ninfo <= 3824) { - n = max(3, (log2(Ninfo)-6)); - Ninfo_prime = max(24, (Ninfo>>n)<= Ninfo_prime) { - TBS = nr_tbs_table[i]; - break; - } - } - else { - n = log2(Ninfo-24)-5; - Ninfo_prime = max(3840, (ROUNDIDIV((Ninfo-24),(1<8424) { - C = CEILIDIV((Ninfo_prime+24),8424); - TBS = (C<<3)*CEILIDIV((Ninfo_prime+24),(C<<3)) - 24; - } - else - TBS = ((CEILIDIV((Ninfo_prime+24),8))<<3) - 24; - } - } + TBS = nr_compute_tbs(Qm, + R, + dlsch_rel15->n_prb, + N_sh_symb, + N_PRB_DMRS, + N_PRB_oh, + dlsch_rel15->nb_layers); dlsch_rel15->coding_rate = R; dlsch_rel15->modulation_order = Qm; dlsch_rel15->transport_block_size = TBS; dlsch_rel15->nb_re_dmrs = N_PRB_DMRS; dlsch_rel15->nb_mod_symbols = N_RE_prime*dlsch_rel15->n_prb*dlsch_rel15->nb_codewords; + dlsch_rel15->mcs_table = table_idx; - LOG_D(MAC, "TBS %d : N_RE %d N_PRB_DMRS %d N_sh_symb %d N_PRB_oh %d Ninfo %d Ninfo_prime %d R %d Qm %d table %d scale %d nb_symbols %d\n", - TBS, N_RE, N_PRB_DMRS, N_sh_symb, N_PRB_oh, Ninfo, Ninfo_prime, R, Qm, table_idx, scale, dlsch_rel15->nb_mod_symbols); + LOG_D(MAC, "TBS %d : N_PRB_DMRS %d N_sh_symb %d N_PRB_oh %d R %d Qm %d table %d nb_symbols %d\n", + TBS, N_PRB_DMRS, N_sh_symb, N_PRB_oh, R, Qm, table_idx, dlsch_rel15->nb_mod_symbols); } uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm, uint8_t Nl) { diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h index 36f3fb5c2c..6a88203f8c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h @@ -48,14 +48,17 @@ #define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1 #define NR_PUSCH_y 3 // UCI placeholder bit -/** \brief Computes Q based on I_MCS PDSCH and table_idx. Implements Table 5.1.3.1-2 from 38.214. */ -uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx); +/** \brief Computes Q based on I_MCS PDSCH and table_idx for downlink. Implements MCS Tables from 38.214. */ +uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx); +uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx); -uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx); +/** \brief Computes Q based on I_MCS PDSCH and table_idx for uplink. Implements MCS Tables from 38.214. */ +uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx); +uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx); -void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, - nfapi_nr_dl_config_dci_dl_pdu dci_pdu, - nfapi_nr_config_request_t config); +void nr_get_tbs_dl(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, + nfapi_nr_dl_config_dci_dl_pdu dci_pdu, + nfapi_nr_config_request_t config); /** \brief Computes available bits G. */ uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint16_t length_dmrs, uint8_t Qm, uint8_t Nl); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index aa5d16f613..8d220a76bb 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -190,4 +190,19 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp, uint32_t nb_rb, uint32_t nb_re, uint8_t symbol, - uint8_t mod_order); \ No newline at end of file + uint8_t mod_order); + +void nr_fill_ulsch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_pusch_pdu_t *ulsch_pdu); + +uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx); + +uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx); + +uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx); + +uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx); + +uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 188c459402..6e991faf37 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -48,6 +48,7 @@ #include "common/utils/LOG/log.h" #include //#define DEBUG_ULSCH_DECODING +#define gNB_DEBUG_TRACE #define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384 //#define PRINT_CRC_CHECK @@ -270,6 +271,10 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) } } +#ifdef PRINT_CRC_CHECK + static uint32_t prnt_crc_cnt = 0; +#endif + uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint8_t UE_id, short *ulsch_llr, @@ -289,7 +294,12 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint8_t crc_type; int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))); - NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id+1][0]; +#ifdef PRINT_CRC_CHECK + prnt_crc_cnt++; +#endif + + + NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0]; NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid]; nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &harq_process->ulsch_pdu.ulsch_pdu_rel15; @@ -310,6 +320,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint16_t nb_rb = nfapi_ulsch_pdu_rel15->number_rbs; uint16_t number_symbols = nfapi_ulsch_pdu_rel15->number_symbols; uint8_t Qm = nfapi_ulsch_pdu_rel15->Qm; + uint16_t R = nfapi_ulsch_pdu_rel15->R; uint8_t mcs = nfapi_ulsch_pdu_rel15->mcs; uint8_t n_layers = nfapi_ulsch_pdu_rel15->n_layers; uint8_t nb_re_dmrs = nfapi_ulsch_pdu_rel15->nb_re_dmrs; @@ -338,8 +349,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, } // harq_process->trials[nfapi_ulsch_pdu_rel15->round]++; - - harq_process->TBS = nr_compute_tbs(mcs, nb_rb, number_symbols, nb_re_dmrs, length_dmrs, n_layers); + harq_process->TBS = nr_compute_tbs(Qm, R, nb_rb, number_symbols, nb_re_dmrs*length_dmrs, 0, n_layers); A = harq_process->TBS; ret = ulsch->max_ldpc_iterations + 1; @@ -353,29 +363,14 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, // This is a new packet, so compute quantities regarding segmentation harq_process->B = A+24; - // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F) - nr_segmentation(NULL, - NULL, - harq_process->B, - &harq_process->C, - &harq_process->K, - &harq_process->Z, // [hna] Z is Zc - &harq_process->F); + if (R<1024) + Coderate = (float) R /(float) 1024; + else + Coderate = (float) R /(float) 2048; -#ifdef DEBUG_ULSCH_DECODING - printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z); - if (!frame%100) - printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, harq_process->Z, harq_process->Nl); -#endif - } - - p_decParams->Z = harq_process->Z; - - Coderate = (float) A /(float) G; - - if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ - p_decParams->BG = 2; - if (Coderate < 0.3333) { + if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ + p_decParams->BG = 2; + if (Coderate < 0.3333) { p_decParams->R = 15; kc = 52; } @@ -403,7 +398,24 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, } } - //printf("coderate %f kc %d \n", Coderate, kc); + // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F) + nr_segmentation(NULL, + NULL, + harq_process->B, + &harq_process->C, + &harq_process->K, + &harq_process->Z, // [hna] Z is Zc + &harq_process->F, + p_decParams->BG); + +#ifdef DEBUG_ULSCH_DECODING + printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z); + if (!frame%100) + printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, harq_process->Z, harq_process->Nl); +#endif + } + p_decParams->Z = harq_process->Z; + p_decParams->numMaxIter = ulsch->max_ldpc_iterations; p_decParams->outMode= 0; @@ -439,8 +451,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, K_bytes_F = Kr_bytes-(harq_process->F>>3); - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, nfapi_ulsch_pdu_rel15->n_layers); - for (r=0; rC; r++) { E = nr_get_E(G, harq_process->C, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers, r); @@ -490,6 +500,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ///////////////////////// harq_process->e =====> harq_process->d ///////////////////////// + Tbslbrm = nr_compute_tbslbrm(0,nb_rb,nfapi_ulsch_pdu_rel15->n_layers,harq_process->C); + if (nr_rate_matching_ldpc_rx(Ilbrm, Tbslbrm, p_decParams->BG, @@ -581,12 +593,14 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { #ifdef PRINT_CRC_CHECK - LOG_I(PHY, "Segment %d CRC OK\n",r); + //if (prnt_crc_cnt % 10 == 0) + LOG_I(PHY, "Segment %d CRC OK\n",r); #endif ret = no_iteration_ldpc; } else { #ifdef PRINT_CRC_CHECK - LOG_I(PHY, "CRC NOK\n"); + //if (prnt_crc_cnt%10 == 0) + LOG_I(PHY, "CRC NOK\n"); #endif ret = ulsch->max_ldpc_iterations + 1; } @@ -632,9 +646,9 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, if (err_flag == 1) { -#if gNB_DEBUG_TRACE - LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", - phy_vars_gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); +#ifdef gNB_DEBUG_TRACE + LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d) Kr %d r %d\n", + phy_vars_gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,Kr,r); #endif // harq_process->harq_ack.ack = 0; @@ -660,9 +674,9 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, } else { -#if gNB_DEBUG_TRACE - LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", - phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); +#ifdef gNB_DEBUG_TRACE + LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n", + phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS); #endif harq_process->status = SCH_IDLE; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index e1b3c5cec9..b961b592d5 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -973,7 +973,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, uint8_t first_symbol_flag, aarx, aatx, pilots; // pilots, a flag to indicate DMRS REs in current symbol NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15; + nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15; uint32_t nb_re_pusch, bwp_start_subcarrier; int avgs; int avg[4]; @@ -986,7 +986,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, first_symbol_flag = 1; } - if (symbol == 2){ // [hna] here it is assumed that symbol 2 carries 6 DMRS REs (dmrs-type 1) + if (symbol == rel15_ul->start_symbol){ // [hna] here it is assumed that first carries 6 DMRS REs (dmrs-type 1) nb_re_pusch = rel15_ul->number_rbs * 6; pilots = 1; } else { @@ -1026,7 +1026,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, frame_parms, - gNB->ulsch[UE_id+1], + gNB->ulsch[UE_id], symbol, pilots, rel15_ul->number_rbs); diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c index 90ef3b0d44..eeee55ea3f 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c +++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c @@ -123,6 +123,30 @@ short filt8_m0[8] = { short filt8_mm0[8]= { 0,0,0,8192,16384,8192,0,0}; +short filt8_dcma[8]= { +16384,12288,8192,4096,4096,0,0,0}; + +short filt8_dcmb[8]= { +0,4096,8192,4096,4096,0,0,0}; + +short filt8_dcmc[8]= { +0,0,0,4096,4096,8192,4096,0}; + +short filt8_dcmd[8]= { +0,0,0,4096,4096,8192,12288,16384}; + +short filt8_dcl0[8]= { +0,0,16384,12288,8192,4096,0,0}; + +short filt8_dcr0[8]= { +0,0,0,4096,8192,12288,16384,0}; + +short filt8_dcl0_h[8]= { +16384,12288,8192,4096,0,0,0,0}; + +short filt8_dcr0_h[8]= { +0,4096,8192,12288,16384,0,0,0}; + short filt8_l1[8] = { 24576,16384,0,0,0,0,0,0}; @@ -136,4 +160,16 @@ short filt8_m1[8] = { 0,0,8192,16384,8192,0,0,0}; short filt8_mm1[8]= { -0,0,0,0,8192,16384,8192,0}; \ No newline at end of file +0,0,0,0,8192,16384,8192,0}; + +short filt8_dcl1[8]= { +0,0,0,16384,12288,8192,4096,0}; + +short filt8_dcr1[8]= { +0,0,0,0,4096,8192,12288,16384}; + +short filt8_dcl1_h[8]= { +0,16384,12288,8192,4096,0,0,0}; + +short filt8_dcr1_h[8]= { +0,0,4096,8192,12288,16384,0,0}; diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h index 9fcad87d7e..f64aebeb52 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h +++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h @@ -91,6 +91,22 @@ extern short filt8_m0[8]; extern short filt8_mm0[8]; +extern short filt8_dcma[8]; + +extern short filt8_dcmb[8]; + +extern short filt8_dcmc[8]; + +extern short filt8_dcmd[8]; + +extern short filt8_dcl0[8]; + +extern short filt8_dcr0[8]; + +extern short filt8_dcl0_h[8]; + +extern short filt8_dcr0_h[8]; + extern short filt8_l1[8]; extern short filt8_ml1[8]; @@ -101,4 +117,11 @@ extern short filt8_m1[8]; extern short filt8_mm1[8]; -#endif \ No newline at end of file +extern short filt8_dcl1[8]; + +extern short filt8_dcr1[8]; + +extern short filt8_dcl1_h[8]; + +extern short filt8_dcr1_h[8]; +#endif diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c index 24ca3d1ad6..cc22e5f7d7 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -60,8 +60,8 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, temp = 0; for (aa=0; aanb_antennas_rx; aa++) { - Re = ((int16_t*)ue->pdcch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_time[aa])[(i<<1)]; - Im = ((int16_t*)ue->pdcch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)]; + Re = ((int16_t*)ue->pbch_vars[eNB_id]->dl_ch_estimates_time[aa])[(i<<1)]; + Im = ((int16_t*)ue->pbch_vars[eNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)]; temp += (Re*Re/2) + (Im*Im/2); } @@ -80,7 +80,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, // do not filter to have proactive timing adjustment //max_pos_fil = max_pos; - if(subframe == 1) + if(subframe == 0) { diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index ab2ac44a9a..752d06fb21 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -21,7 +21,7 @@ #include - +#include "SCHED_NR_UE/defs.h" #include "nr_estimation.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "filt16a_32.h" @@ -98,8 +98,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -114,8 +113,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; current_ssb->c_re +=ch[0]; @@ -126,8 +124,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt+=3) { @@ -138,8 +135,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) if (dmrss == 1 && pilot_cnt == 12) { pilot_cnt=48; - //re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 144) : (re_offset+144); + re_offset = (re_offset+144) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; } ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -153,8 +149,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -168,8 +163,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -184,8 +178,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; } @@ -199,19 +192,23 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, - uint8_t eNB_offset, - unsigned char Ns, - unsigned char symbol, - int dmrss, - uint8_t ssb_index, - uint8_t n_hf) + uint8_t eNB_offset, + unsigned char Ns, + unsigned char symbol, + int dmrss, + uint8_t ssb_index, + uint8_t n_hf) { int pilot[200] __attribute__((aligned(16))); - unsigned char aarx; + unsigned char aarx,p; unsigned short k; unsigned int pilot_cnt; int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr; int ch_offset,symbol_offset; + int slot_pbch; + fapi_nr_pbch_config_t *pbch_config = &ue->nrUE_config.pbch_config; + // initialized to 5ms in nr_init_ue for scenarios where UE is not configured (otherwise acquired by cell configuration from gNB or LTE) + uint8_t ssb_periodicity = 10;// ue->ssb_periodicity; //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; @@ -310,8 +307,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; //for (int i= 0; i<8; i++) @@ -329,8 +325,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -345,8 +340,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; dl_ch+=24; @@ -358,8 +352,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) if (dmrss == 1 && pilot_cnt == 12) { pilot_cnt=48; - //re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 144) : (re_offset+144); + re_offset = (re_offset+144) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; dl_ch += 288; } @@ -378,8 +371,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i)); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -394,8 +386,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -411,13 +402,65 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; dl_ch+=24; } + void (*idft)(int16_t *,int16_t *, int); + + switch (ue->frame_parms.ofdm_symbol_size) { + case 128: + idft = idft128; + break; + + case 256: + idft = idft256; + break; + + case 512: + idft = idft512; + break; + + case 1024: + idft = idft1024; + break; + + case 1536: + idft = idft1536; + break; + + case 2048: + idft = idft2048; + break; + + case 3072: + idft = idft3072; + break; + + case 4096: + idft = idft4096; + break; + + default: + printf("unsupported ofdm symbol size \n"); + assert(0); + } + + if( symbol == 3) + { + // do ifft of channel estimate + for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) + for (p=0; pframe_parms.nb_antenna_ports_eNB; p++) { + if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx]) + { + LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, ue->current_thread_id[Ns], symbol, ch_offset); + idft((int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx][ch_offset], + (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1); + } + } + } //} @@ -433,7 +476,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned short nb_rb_coreset) { int pilot[200] __attribute__((aligned(16))); - unsigned char aarx,p; + unsigned char aarx; unsigned short k; unsigned int pilot_cnt; int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr; @@ -597,60 +640,6 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, //} } - - void (*idft)(int16_t *,int16_t *, int); - - switch (ue->frame_parms.ofdm_symbol_size) { - case 128: - idft = idft128; - break; - - case 256: - idft = idft256; - break; - - case 512: - idft = idft512; - break; - - case 1024: - idft = idft1024; - break; - - case 1536: - idft = idft1536; - break; - - case 2048: - idft = idft2048; - break; - - case 3072: - idft = idft3072; - break; - - case 4096: - idft = idft4096; - break; - - default: - printf("unsupported ofdm symbol size \n"); - assert(0); - } - - if( (Ns== 1) && (symbol == 0)) - { - // do ifft of channel estimate - for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) - for (p=0; pframe_parms.nb_antenna_ports_eNB; p++) { - if (ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates[(p<<1)+aarx]) - { - LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns], symbol); - idft((int16_t*) &ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates[(p<<1)+aarx][0], - (int16_t*) ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1); - } - } - } return(0); } @@ -663,11 +652,12 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned short bwp_start_subcarrier, unsigned short nb_rb_pdsch) { - int pilot[1320] __attribute__((aligned(16))); + int pilot[3280] __attribute__((aligned(16))); unsigned char aarx; unsigned short k; unsigned int pilot_cnt; - int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr,*fml,*fmr,*fmm; + int16_t ch[2],*pil,*rxF,*dl_ch; + int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh; int ch_offset,symbol_offset; //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; @@ -702,6 +692,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, fmm = filt8_mm0; fml = filt8_m0; fmr = filt8_mr0; + fdcl = filt8_dcl0; + fdcr = filt8_dcr0; + fdclh = filt8_dcl0_h; + fdcrh = filt8_dcr0_h; break; case 1: @@ -711,6 +705,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, fmm = filt8_mm1; fml = filt8_ml1; fmr = filt8_m1; + fdcl = filt8_dcl1; + fdcr = filt8_dcr1; + fdclh = filt8_dcl1_h; + fdcrh = filt8_dcr1_h; break; default: @@ -721,11 +719,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, // generate pilot - nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][0], &pilot[0],1000,0,nb_rb_pdsch); + uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12; + int config_type = 0; // needs to be updated from higher layer + nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][0], &pilot[0],1000,0,nb_rb_pdsch+rb_offset); for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { - pil = (int16_t *)&pilot[0]; + pil = (int16_t *)&pilot[rb_offset*((config_type==0) ? 6:4)]; + k = k % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; @@ -755,8 +756,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //for (int i= 0; i<8; i++) //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); @@ -771,8 +771,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //printf("dl_ch addr %p\n",dl_ch); @@ -790,8 +789,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; dl_ch+=8; @@ -811,8 +809,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -825,15 +822,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; dl_ch+=8; } // Treat first 2 pilots specially (right edge) - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDSCH printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); @@ -847,8 +843,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -863,8 +858,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; dl_ch+=8; @@ -878,7 +872,70 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); //} + + // check if PRB crosses DC and improve estimates around DC + if ((bwp_start_subcarrier >= ue->frame_parms.ofdm_symbol_size/2) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size)) { + dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; + uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); + uint16_t idxPil = idxDC/2; + re_offset = k; + pil = (int16_t *)&pilot[rb_offset*((config_type==0) ? 6:4)]; + pil += (idxPil-2); + dl_ch += (idxDC-4); + dl_ch = memset(dl_ch, 0, sizeof(int16_t)*10); + re_offset = (re_offset+idxDC/2-2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + // for proper allignment of SIMD vectors + if((ue->frame_parms.N_RB_DL&1)==0) { + + multadd_real_vector_complex_scalar(fdcl, + ch, + dl_ch-4, + 8); + + pil += 4; + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + multadd_real_vector_complex_scalar(fdcr, + ch, + dl_ch-4, + 8); + } else { + multadd_real_vector_complex_scalar(fdclh, + ch, + dl_ch, + 8); + + pil += 4; + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + multadd_real_vector_complex_scalar(fdcrh, + ch, + dl_ch, + 8); + } + + } + +#ifdef DEBUG_PDSCH + dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; + for(uint16_t idxP=0; idxPframe_parms.ofdm_symbol_size*2; -printf("testing measurements\n"); +//printf("testing measurements\n"); // signal measurements for (eNB_id=0; eNB_idn_connected_eNB; eNB_id++) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 3f206a679c..de88858c2d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -140,9 +140,7 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr, } f_reg = (f_bundle_j*reg_bundle_size_L)+(reg%reg_bundle_size_L); - //index_z = 9*reg; - index_z = 9*(uint16_t)floor(reg/coreset_time_dur) + (9*coreset_nbr_rb)*(reg%coreset_time_dur); - //index_llr = 9*(((uint16_t)floor(f_reg/reg_bundle_size_L)+(f_reg)%coreset_time_dur))*(coreset_nbr_rb); + index_z = 9*reg; index_llr = 9*((uint16_t)floor(f_reg/coreset_time_dur)+((f_reg%coreset_time_dur)*(coreset_nbr_rb))); for (int i=0; i<9; i++) { @@ -395,7 +393,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, if (((c_rb - n_BWP_start) % BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN)==0) { bitcnt_coreset_freq_dom ++; - while ((((coreset_freq_dom & 0x1FFFFFFFFFFF) >> (CORESET_FREQ_DOMAIN_BITMAP_SIZE - bitcnt_coreset_freq_dom)) & 0x1)== 0) { // 46 -> 45 is number of bits in coreset_freq_dom + while ((((coreset_freq_dom & 0x1FFFFFFFFFFF) >> (CORESET_FREQ_DOMAIN_BITMAP_SIZE - (n_BWP_start/BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN) - bitcnt_coreset_freq_dom)) & 0x1)== 0) { // 46 -> 45 is number of bits in coreset_freq_dom // next 6 RB are not part of the CORESET within the BWP as bit in coreset_freq_dom is set to 0 bitcnt_coreset_freq_dom ++; //c_rb_tmp = c_rb_tmp + 6; @@ -1340,6 +1338,7 @@ void nr_dci_decoding_procedure0(int s, const t_nrPolar_params *currentPtrDCI=nr_polar_params(1, sizeof_bits, L2); decoderState = polar_decoder_int16(&pdcch_vars[eNB_id]->e_rx[CCEind*9*6*2], dci_estimation, + 1, currentPtrDCI); crc = decoderState; //crc = (crc16(&dci_decoded_output[current_thread_id][0], sizeof_bits) >> 16) ^ extract_crc(&dci_decoded_output[current_thread_id][0], sizeof_bits); diff --git a/openair1/PHY/NR_UE_TRANSPORT/dmrs_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dmrs_nr.c index d976ec5a04..4d77854a70 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dmrs_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dmrs_nr.c @@ -258,7 +258,7 @@ uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position) { * *********************************************************************/ -uint16_t get_dmrs_freq_idx_ul(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) { +uint16_t get_dmrs_freq_idx_ul(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) { uint16_t dmrs_idx; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index b7be5d9cd6..53d481919e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -239,7 +239,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, //__m128i l; //int16_t inv_d [68*384]; uint8_t kc; - uint8_t Ilbrm = 0; + uint8_t Ilbrm = 1; uint32_t Tbslbrm; //= 950984; uint16_t nb_rb; //= 30; double Coderate; //= 0.0; @@ -299,12 +299,14 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, harq_process->trials[harq_process->round]++; - harq_process->TBS = nr_compute_tbs(harq_process->mcs,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl); + uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs + + harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl); A = harq_process->TBS; ret = dlsch->max_ldpc_iterations + 1; dlsch->last_iteration_cnt = ret; - + harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, harq_process->Qm,harq_process->Nl); G = harq_process->G; @@ -312,29 +314,11 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN); - if (harq_process->round == 0) { - // This is a new packet, so compute quantities regarding segmentation - harq_process->B = A+24; - nr_segmentation(NULL, - NULL, - harq_process->B, - &harq_process->C, - &harq_process->K, - &harq_process->Z, // [hna] Z is Zc - &harq_process->F); + if ((harq_process->R)<1024) + Coderate = (float) (harq_process->R) /(float) 1024; + else + Coderate = (float) (harq_process->R) /(float) 2048; -#ifdef DEBUG_DLSCH_DECODING - if (!frame%100) - printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl); -#endif - } - - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT); - - p_decParams->Z = harq_process->Z; - //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z); - - Coderate = (float) A /(float) G; if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) { p_decParams->BG = 2; @@ -367,6 +351,34 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, } } + + if (harq_process->round == 0) { + // This is a new packet, so compute quantities regarding segmentation + if (A > 3824) + harq_process->B = A+24; + else + harq_process->B = A+16; + + nr_segmentation(NULL, + NULL, + harq_process->B, + &harq_process->C, + &harq_process->K, + &harq_process->Z, // [hna] Z is Zc + &harq_process->F, + p_decParams->BG); + +#ifdef DEBUG_DLSCH_DECODING + if (!frame%100) + printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl); +#endif + } + + vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT); + + p_decParams->Z = harq_process->Z; + //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z); + //printf("coderate %f kc %d \n", Coderate, kc); p_decParams->numMaxIter = dlsch->max_ldpc_iterations; @@ -403,8 +415,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, K_bytes_F = Kr_bytes-(harq_process->F>>3); - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl); - for (r=0; rC; r++) { //printf("start rx segment %d\n",r); @@ -448,6 +458,11 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN); + if ((harq_process->Nl)<4) + Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C); + else + Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C); + if (nr_rate_matching_ldpc_rx(Ilbrm, Tbslbrm, p_decParams->BG, @@ -495,8 +510,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, // printf("done\n"); if (harq_process->C == 1){ - crc_type = CRC24_A; - length_dec = harq_process->B; + if (A > 3824) + crc_type = CRC24_A; + else + crc_type = CRC16; + + length_dec = harq_process->B; + } else{ crc_type = CRC24_B; @@ -544,13 +564,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - printf("\x1B[34m" "Segment %d CRC OK\n",r); + printf("\x1B[34m" "Segment %d CRC OK\n\033[0m",r); //Temporary hack no_iteration_ldpc = dlsch->max_ldpc_iterations; ret = no_iteration_ldpc; } else { - printf("\x1B[33m" "CRC NOK\n"); + printf("\x1B[33m" "CRC NOK\n\033[0m"); ret = 1 + dlsch->max_ldpc_iterations; } @@ -739,7 +759,6 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, int32_t no_iteration_ldpc,length_dec; /*uint8_t C; uint8_t Qm; - uint8_t Nl; uint8_t r_thread; uint32_t Er, Gp,GpmodC;*/ t_nrLDPC_dec_params decParams; @@ -748,14 +767,14 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, t_nrLDPC_time_stats* p_procTime =&procTime ; int8_t llrProcBuf[OAI_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))); t_nrLDPC_procBuf* p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[0]; - + uint8_t Nl=4; int16_t z [68*384]; int8_t l [68*384]; //__m128i l; int16_t inv_d [68*384]; //int16_t *p_invd =&inv_d; uint8_t kb, kc; - uint8_t Ilbrm = 0; + uint8_t Ilbrm = 1; uint32_t Tbslbrm = 950984; uint16_t nb_rb = 30; double Coderate = 0.0; @@ -813,7 +832,9 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, nb_rb = harq_process->nb_rb; harq_process->trials[harq_process->round]++; - harq_process->TBS = nr_compute_tbs(harq_process->mcs,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl); + uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs + + harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl); A = harq_process->TBS; @@ -833,22 +854,11 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, // printf("DLSCH Decoding, harq_pid %d Ndi %d\n",harq_pid,harq_process->Ndi); - if (harq_process->round == 0) { - // This is a new packet, so compute quantities regarding segmentation - harq_process->B = A+24; - nr_segmentation(NULL, - NULL, - harq_process->B, - &harq_process->C, - &harq_process->K, - &harq_process->Z, - &harq_process->F); + if ((harq_process->R)<1024) + Coderate = (float) (harq_process->R) /(float) 1024; + else + Coderate = (float) (harq_process->R) /(float) 2048; - p_decParams->Z = harq_process->Z; - - } - - Coderate = (float) A /(float) G; if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) { p_decParams->BG = 2; @@ -881,6 +891,26 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, } } + if (harq_process->round == 0) { + // This is a new packet, so compute quantities regarding segmentation + if (A > 3824) + harq_process->B = A+24; + else + harq_process->B = A+16; + + nr_segmentation(NULL, + NULL, + harq_process->B, + &harq_process->C, + &harq_process->K, + &harq_process->Z, + &harq_process->F, + p_decParams->BG); + + p_decParams->Z = harq_process->Z; + + } + //printf("coderate %f kc %d \n", Coderate, kc); p_decParams->numMaxIter = dlsch->max_ldpc_iterations; p_decParams->outMode= 0; @@ -959,8 +989,6 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, Kr_bytes = Kr>>3; K_bytes_F = Kr_bytes-(harq_process->F>>3); - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl); - E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r); /* @@ -1001,6 +1029,12 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, harq_process->round); #endif + // for tbslbrm calculation according to 5.4.2.1 of 38.212 + if (harq_process->Nl < Nl) + Nl = harq_process->Nl; + + Tbslbrm = nr_compute_tbslbrm(rel15.mcs_table,nb_rb,Nl,dlsch->harq_processes[harq_pid]->C); + if (nr_rate_matching_ldpc_rx(Ilbrm, Tbslbrm, p_decParams->BG, @@ -1053,7 +1087,11 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, // printf("done\n"); if (harq_process->C == 1){ - crc_type = CRC24_A; + if (A > 3824) + crc_type = CRC24_A; + else + crc_type = CRC16; + length_dec = harq_process->B; } else{ @@ -1304,7 +1342,7 @@ void *nr_dlsch_decoding_process(void *arg) int16_t inv_d [68*384]; int16_t *p_invd =&inv_d; uint8_t kb, kc; - uint8_t Ilbrm = 0; + uint8_t Ilbrm = 1; uint32_t Tbslbrm = 950984; uint16_t nb_rb = 30; //to update double Coderate = 0.0; @@ -1344,8 +1382,8 @@ void *nr_dlsch_decoding_process(void *arg) int harq_pid = proc->harq_pid; llr8_flag1 = proc->llr8_flag; int frame = proc->frame_rx; - int slot = proc->nr_tti_rx; - r = proc->num_seg; + int slot = proc->nr_tti_rx; + r = proc->num_seg; NR_UE_DLSCH_t *dlsch = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[slot]][eNB_id][0]; NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[harq_pid]; @@ -1373,7 +1411,9 @@ void *nr_dlsch_decoding_process(void *arg) harq_process->trials[harq_process->round]++; - harq_process->TBS = nr_compute_tbs(harq_process->mcs,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl); + uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs + + harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl); A = harq_process->TBS; //2072 for QPSK 1/3 @@ -1385,23 +1425,11 @@ void *nr_dlsch_decoding_process(void *arg) LOG_I(PHY,"DLSCH Decoding process, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb); - - if (harq_process->round == 0) { - // This is a new packet, so compute quantities regarding segmentation - harq_process->B = A+24; + if ((harq_process->R)<1024) + Coderate = (float) (harq_process->R) /(float) 1024; + else + Coderate = (float) (harq_process->R) /(float) 2048; - nr_segmentation(NULL, - NULL, - harq_process->B, - &harq_process->C, - &harq_process->K, - &harq_process->Z, - &harq_process->F); - p_decParams->Z = harq_process->Z; - - } - - Coderate = (float) A /(float) G; if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) { p_decParams->BG = 2; @@ -1432,7 +1460,29 @@ void *nr_dlsch_decoding_process(void *arg) p_decParams->R = 89; kc = 27; } - } + } + + if (harq_process->round == 0) { + // This is a new packet, so compute quantities regarding segmentation + if (A > 3824) + harq_process->B = A+24; + else + harq_process->B = A+16; + + nr_segmentation(NULL, + NULL, + harq_process->B, + &harq_process->C, + &harq_process->K, + &harq_process->Z, + &harq_process->F, + p_decParams->BG); + + p_decParams->Z = harq_process->Z; + + } + + p_decParams->numMaxIter = dlsch->max_ldpc_iterations; p_decParams->outMode= 0; @@ -1492,9 +1542,7 @@ void *nr_dlsch_decoding_process(void *arg) Kr_bytes = Kr>>3; K_bytes_F = Kr_bytes-(harq_process->F>>3); - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl); - - E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r); + E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r); #if UE_TIMING_TRACE start_meas(dlsch_deinterleaving_stats); @@ -1529,6 +1577,11 @@ void *nr_dlsch_decoding_process(void *arg) harq_process->round); #endif + if (Nl<4) + Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl,harq_process->C); + else + Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C); + if (nr_rate_matching_ldpc_rx(Ilbrm, Tbslbrm, p_decParams->BG, @@ -1573,7 +1626,11 @@ void *nr_dlsch_decoding_process(void *arg) memset(harq_process->c[r],0,Kr_bytes); if (harq_process->C == 1){ - crc_type = CRC24_A; + if (A > 3824) + crc_type = CRC24_A; + else + crc_type = CRC16; + length_dec = harq_process->B; } else{ diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 79b5c8d909..8f810d36d3 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -176,7 +176,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id]; - dlsch[0]->harq_processes[harq_pid]->Qm = nr_get_Qm(dlsch[0]->harq_processes[harq_pid]->mcs, 1);; + dlsch[0]->harq_processes[harq_pid]->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table); + dlsch[0]->harq_processes[harq_pid]->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table); //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status); LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", @@ -964,7 +965,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, break; } if (dlsch1_harq) { - switch (nr_get_Qm(dlsch1_harq->mcs, 1)) { + switch (nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table)) { case 2 : if (rx_type==rx_standard) { nr_dlsch_qpsk_llr(frame_parms, @@ -2379,10 +2380,13 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, unsigned char j=0; - k = frame_parms->first_carrier_offset + 12*start_rb; + AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 1, + "nushift %d is illegal\n",frame_parms->nushift); for (aarx=0; aarxnb_antennas_rx; aarx++) { + k = frame_parms->first_carrier_offset + 12*start_rb; + if (high_speed_flag == 1) dl_ch0 = &dl_ch_estimates[aarx][(2*(frame_parms->ofdm_symbol_size))]; else @@ -2393,65 +2397,43 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, rxF_ext = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)]; rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; - //printf("extract single addr %p pilots %d symbol %d, l %d RB_DL %d nushift %d k %d\n", rxF, pilots, symbol, l, frame_parms->N_RB_DL,frame_parms->nushift,k); - - //if ((frame_parms->N_RB_DL&1) == 0){ // even number of RBs - - for (rb = start_rb; rb < nb_rb_pdsch + start_rb; rb++) { - - // For second half of RBs skip DC carrier - if (k>=frame_parms->ofdm_symbol_size) { - rxF = &rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))]; - k=k-(frame_parms->ofdm_symbol_size); + for (rb = 0; rb < nb_rb_pdsch; rb++) { + if (k>frame_parms->ofdm_symbol_size) { + k = k-frame_parms->ofdm_symbol_size; + rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; } - - //*pmi_ext = (pmi>>((rb>>2)<<1))&3; - //memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); - - /* - printf("rb %d\n",rb); - for (i=0;i<12;i++) - printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]); - printf("\n"); - */ - if (pilots==0) { - for (i=0; i<12; i++) { - rxF_ext[i]=rxF[i]; - dl_ch0_ext[i]=dl_ch0[i]; - /*printf("rb %ld %p: (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]),rxF, - ((short*)&rxF[i])[0],((short*)&rxF[i])[1]); - printf("rb %ld %p: dl_ch (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]),rxF, - ((short*)&dl_ch0[i])[0],((short*)&dl_ch0[i])[1]); - printf("re count %d\n",rb*12+i);*/ - } - - dl_ch0_ext+=12; - rxF_ext+=12; - } else { - j=0; - - for (i=0; i<12; i++) { - if ((i&1)!=frame_parms->nushift){ - rxF_ext[j]=rxF[i]; - //printf("extract rb %d, re %d => rxF (%d,%d) rxF ext (%d,%d) addr %p\n",rb,i,*(short *)&rxF[i],*(1+(short*)&rxF[i]),*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]),rxF_ext); - dl_ch0_ext[j]=dl_ch0[i]; - //printf("rb %ld %p: dl_ch (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]),rxF, - //((short*)&dl_ch0[i])[0],((short*)&dl_ch0[i])[1]); - j++; - } - } - - dl_ch0_ext+=6; - rxF_ext+=6; - } - - dl_ch0+=12; - rxF+=12; - k+=12; + if (pilots==0) { + memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext)); + memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext)); + dl_ch0_ext+=12; + rxF_ext+=12; + } else { + j=0; + + for (i = (1-frame_parms->nushift); + i<12; + i+=2) { + rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + + + dl_ch0_ext+=6; + rxF_ext+=6; } + + dl_ch0+=12; + rxF+=12; + k+=12; + if (k>=frame_parms->ofdm_symbol_size) { + k=k-(frame_parms->ofdm_symbol_size); + rxF = &rxdataF[aarx][k+(symbol*(frame_parms->ofdm_symbol_size))]; + } + } } - - + + return(nb_rb_pdsch/frame_parms->nb_antennas_rx); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 3d8ec866c6..1e17f6dab0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -538,7 +538,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_E,0,0); //polar decoding de-rate matching const t_nrPolar_params *currentPtr = nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL); - decoderState = polar_decoder_int16(pbch_e_rx,(uint64_t *)&nr_ue_pbch_vars->pbch_a_prime,currentPtr); + decoderState = polar_decoder_int16(pbch_e_rx,(uint64_t *)&nr_ue_pbch_vars->pbch_a_prime,0,currentPtr); if(decoderState) return(decoderState); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 6c14aa8b56..7559115a29 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -1064,7 +1064,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, */ void nr_pusch_codeword_scrambling(uint8_t *in, - uint16_t size, + uint32_t size, uint32_t Nid, uint32_t n_RNTI, uint32_t* out); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index 376c8b90db..39b037a600 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -265,10 +265,14 @@ typedef struct { uint8_t *c[MAX_NUM_NR_DLSCH_SEGMENTS]; /// Index of current HARQ round for this DLSCH uint8_t round; + /// MCS table for this DLSCH + uint8_t mcs_table; /// MCS format for this DLSCH uint8_t mcs; /// Qm (modulation order) for this DLSCH uint8_t Qm; + /// target code rate R x 1024 + uint16_t R; /// Redundancy-version of the current sub-frame uint8_t rvidx; /// MIMO mode for this DLSCH diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index bc986e2918..cbe0a816ff 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -202,11 +202,12 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, uint8_t mod_order; uint16_t Kr,r,r_offset; uint8_t BG; - uint32_t E; + uint32_t E,Kb; uint8_t Ilbrm; uint32_t Tbslbrm; uint8_t nb_re_dmrs; uint16_t length_dmrs; + uint16_t R; float Coderate; /////////// @@ -222,7 +223,8 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, nb_symb_sch = harq_process->number_of_symbols; A = harq_process->TBS; pz = &Z; - mod_order = nr_get_Qm(harq_process->mcs,1); + mod_order = nr_get_Qm_ul(harq_process->mcs,0); + R = nr_get_code_rate_ul(harq_process->mcs, 0); Kr=0; r_offset=0; BG = 1; @@ -250,9 +252,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,harq_process->Nl); LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order); - - - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl); // if (harq_process->Ndi == 1) { // this is a new packet if (harq_process->round == 0) { // this is a new packet @@ -287,16 +286,10 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, ///////////////////////// b---->| block segmentation |---->c ///////////////////////// /////////// - nr_segmentation(harq_process->b, - harq_process->c, - harq_process->B, - &harq_process->C, - &harq_process->K, - pz, - &harq_process->F); - - F = harq_process->F; - Coderate = (float) A /(float) G; + if (R<1024) + Coderate = (float) R /(float) 1024; + else + Coderate = (float) R /(float) 2048; if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ BG = 2; @@ -305,6 +298,16 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, BG = 1; } + Kb=nr_segmentation(harq_process->b, + harq_process->c, + harq_process->B, + &harq_process->C, + &harq_process->K, + pz, + &harq_process->F, + BG); + + F = harq_process->F; Kr = harq_process->K; #ifdef DEBUG_DLSCH_CODING uint16_t Kr_bytes; @@ -349,7 +352,7 @@ opp_enabled=0; } printf("\n");*/ - ldpc_encoder_optim_8seg(harq_process->c,harq_process->d,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL); + ldpc_encoder_optim_8seg(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL); //stop_meas(te_stats); //printf("end ldpc encoder -- output\n"); @@ -391,6 +394,8 @@ opp_enabled=0; E = nr_get_E(G, harq_process->C, mod_order, harq_process->Nl, r); + Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->Nl,harq_process->C); + nr_rate_matching_ldpc(Ilbrm, Tbslbrm, BG, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 79a2fc9f5c..12aaebc917 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -46,7 +46,7 @@ //#define DEBUG_PUSCH_MAPPING void nr_pusch_codeword_scrambling(uint8_t *in, - uint16_t size, + uint32_t size, uint32_t Nid, uint32_t n_RNTI, uint32_t* out) { @@ -90,7 +90,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint8_t thread_id, int gNB_id) { - unsigned int available_bits; + uint32_t available_bits; uint8_t mod_order, cwd_index, num_of_codewords; uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; uint32_t ***pusch_dmrs; @@ -98,7 +98,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, int32_t **txdataF; uint16_t start_sc, start_rb; int8_t Wf[2], Wt[2], l0, l_prime[2], delta; - uint16_t n_dmrs; + uint16_t n_dmrs,code_rate; uint8_t dmrs_type, length_dmrs; uint8_t mapping_type; int ap, start_symbol, Nid_cell, i; @@ -130,14 +130,25 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*harq_process_ul_ue->nb_rb*num_of_codewords; - harq_process_ul_ue->TBS = nr_compute_tbs( harq_process_ul_ue->mcs, harq_process_ul_ue->nb_rb, harq_process_ul_ue->number_of_symbols, ulsch_ue->nb_re_dmrs, ulsch_ue->length_dmrs, harq_process_ul_ue->Nl); + mod_order = nr_get_Qm_ul(harq_process_ul_ue->mcs, 0); + code_rate = nr_get_code_rate_ul(harq_process_ul_ue->mcs, 0); + + harq_process_ul_ue->TBS = nr_compute_tbs(mod_order, + code_rate, + harq_process_ul_ue->nb_rb, + harq_process_ul_ue->number_of_symbols, + ulsch_ue->nb_re_dmrs*ulsch_ue->length_dmrs, + 0, + harq_process_ul_ue->Nl); //-----------------------------------------------------// // to be removed later when MAC is ready if (harq_process_ul_ue != NULL){ - for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) + for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) { harq_process_ul_ue->a[i] = (unsigned char) rand(); + //printf("input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); + } } else { LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n"); return; @@ -156,7 +167,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////ULSCH scrambling///////////////////////// /////////// - mod_order = nr_get_Qm(harq_process_ul_ue->mcs, 1); + mod_order = nr_get_Qm_ul(harq_process_ul_ue->mcs, 0); available_bits = nr_get_G(harq_process_ul_ue->nb_rb, harq_process_ul_ue->number_of_symbols, diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index af895ba556..778070b347 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -589,8 +589,8 @@ void phy_scope_nrUE(FD_phy_scope_nrue *form, time = calloc(samples_per_frame,sizeof(float)); corr = calloc(samples_per_frame,sizeof(float)); - chest_t = (int16_t**) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_time; - chest_f = (int16_t**) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates; + chest_t = (int16_t**) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates_time; + chest_f = (int16_t**) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates; pbch_llr = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->llr; pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0]; @@ -697,8 +697,8 @@ void phy_scope_nrUE(FD_phy_scope_nrue *form, if (chest_f[(atx<<1)+arx] != NULL) { for (k=0; kofdm_symbol_size; k++) { freq[ind] = (float)ind; - Re = (float)(chest_f[(atx<<1)+arx][(2*k)]); - Im = (float)(chest_f[(atx<<1)+arx][(2*k)+1]); + Re = (float)(chest_f[(atx<<1)+arx][6144+(2*k)]); + Im = (float)(chest_f[(atx<<1)+arx][6144+(2*k)+1]); chest_f_abs[ind] = (short)10*log10(1.0+((double)Re*Re + (double)Im*Im)); ind++; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index c8b1f44f3f..3746af85aa 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -616,6 +616,7 @@ typedef struct PHY_VARS_gNB_s { NR_IF_Module_t *if_inst; NR_UL_IND_t UL_INFO; pthread_mutex_t UL_INFO_mutex; + /// NFAPI RX ULSCH information nfapi_rx_indication_pdu_t rx_pdu_list[NFAPI_RX_IND_MAX_PDU]; /// NFAPI RX ULSCH CRC information @@ -631,19 +632,16 @@ typedef struct PHY_VARS_gNB_s { /// NFAPI PRACH information nfapi_preamble_pdu_t preamble_list[MAX_NUM_RX_PRACH_PREAMBLES]; - Sched_Rsp_t Sched_INFO; + //Sched_Rsp_t Sched_INFO; + nfapi_nr_ul_tti_request_t UL_tti_req; + NR_gNB_PDCCH pdcch_vars; NR_gNB_PBCH pbch; - // LTE_eNB_PHICH phich_vars[2]; NR_gNB_COMMON common_vars; -/* LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX]; - LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX]; - LTE_eNB_PRACH prach_vars;*/ NR_gNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX]; NR_gNB_DLSCH_t *dlsch[NUMBER_OF_NR_DLSCH_MAX][2]; // Nusers times two spatial streams - NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX+1][2]; // [Nusers times + number of RA][2 codewords], index 0 in [NUMBER_OF_UE_MAX+1] is for RA - // LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA + NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX][2]; // [Nusers times][2 codewords] NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p; NR_gNB_DLSCH_t *dlsch_PCH; /* diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 075650907b..19f4365a29 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -810,6 +810,10 @@ typedef struct { /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..287] (hard coded) int32_t **dl_ch_estimates_ext; + /// \brief Hold the channel estimates in time domain (used for tracking). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: samples? [0..2*ofdm_symbol_size[ + int32_t **dl_ch_estimates_time; int log2_maxh; uint8_t pbch_a[NR_POLAR_PBCH_PAYLOAD_BITS>>3]; uint32_t pbch_a_interleaved; @@ -990,7 +994,7 @@ typedef struct { uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD]; /// PDSCH DMRS - uint32_t nr_gold_pdsch[2][20][2][52]; + uint32_t nr_gold_pdsch[2][20][2][NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD]; /// PDCCH DMRS uint32_t nr_gold_pdcch[7][20][3][52]; diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 2f99973290..793e26232f 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -30,6 +30,7 @@ * \warning */ #include "fapi_nr_l1.h" +#include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_dci.h" @@ -127,6 +128,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ uint8_t CC_id = Sched_INFO->CC_id; nfapi_nr_dl_config_request_t *DL_req = Sched_INFO->DL_req; nfapi_tx_request_t *TX_req = Sched_INFO->TX_req; + nfapi_nr_ul_tti_request_t *UL_tti_req = Sched_INFO->UL_tti_req; frame_t frame = Sched_INFO->frame; sub_frame_t slot = Sched_INFO->slot; @@ -137,6 +139,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ gNB = RC.gNB[Mod_id][CC_id]; uint8_t number_dl_pdu = DL_req->dl_config_request_body.number_pdu; + uint8_t number_ul_pdu = UL_tti_req->n_pdus; nfapi_nr_dl_config_request_pdu_t *dl_config_pdu; @@ -195,6 +198,22 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ } } + memcpy(&gNB->UL_tti_req,UL_tti_req,sizeof(nfapi_nr_ul_tti_request_t)); + + /* + // this is done in phy_procedures_gNB_uespec_RX now + for (i=0;ipdus_list[i].pdu_type); + switch (UL_tti_req->pdus_list[i].pdu_type) { + case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: + { + nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; + nr_fill_ulsch(gNB,frame,slot,pusch_pdu); + } + } + } + */ + if (nfapi_mode && do_oai && !dont_send) { oai_nfapi_tx_req(Sched_INFO->TX_req); diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index c4693bd263..a4318f1d60 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -125,12 +125,15 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) { int ret = 0; int nb_antenna_ports = fp->N_ssb; int ofdm_mask_full = (1<<(ru->nb_tx*2))-1; + int txdataF_offset = ((tti_tx%2)*fp->samples_per_slot_wCP); if (nr_slot_select(cfg,slot) == SF_UL) return; for (aa=0; aaLmax; aa++) { memset(ru->common.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t)); } + start_meas(&ru->ofdm_total_stats); + for(j=0; jsymbols_per_slot; ++j){ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 1); @@ -141,7 +144,7 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) { for(i=0; icommon.txdataF[i][j*fp->ofdm_symbol_size], - (void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + ((tti_tx%2)*fp->samples_per_slot_wCP)], + (void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + txdataF_offset], fp->ofdm_symbol_size*sizeof(int32_t)); } diff --git a/openair1/SCHED_NR/phy_procedures_nr_common.c b/openair1/SCHED_NR/phy_procedures_nr_common.c index abc1c44ce5..7edd0fb9b8 100755 --- a/openair1/SCHED_NR/phy_procedures_nr_common.c +++ b/openair1/SCHED_NR/phy_procedures_nr_common.c @@ -36,7 +36,7 @@ nr_subframe_t nr_slot_select(nfapi_nr_config_request_t *cfg, unsigned char slot) { - if (cfg->subframe_config.duplex_mode.value == FDD || slot == NR_DOWNLINK_SLOT || nr_is_ssb_slot(cfg, slot) == 1) + if (cfg->subframe_config.duplex_mode.value == FDD || slot == NR_DOWNLINK_SLOT) return(SF_DL); else if (slot == NR_UPLINK_SLOT) return (SF_UL); diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 5fe9d8b103..47690726bb 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -184,32 +184,30 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, num_dci = gNB->pdcch_vars.num_dci; num_pdsch_rnti = gNB->pdcch_vars.num_pdsch_rnti; - if (num_dci) { + for (int i=0; iMod_id, frame, slot, num_dci); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,1); - if (nfapi_mode == 0 || nfapi_mode == 1) { - nr_generate_dci_top(gNB->pdcch_vars, - gNB->nr_gold_pdcch_dmrs[slot], - &gNB->common_vars.txdataF[0][txdataF_offset], // hardcoded to beam 0 - AMP, *fp, *cfg); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0); - if (num_pdsch_rnti) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1); - LOG_D(PHY, "PDSCH generation started (%d)\n", num_pdsch_rnti); - nr_generate_pdsch(gNB->dlsch[0][0], - &gNB->pdcch_vars.dci_alloc[0], - gNB->nr_gold_pdsch_dmrs[slot], - gNB->common_vars.txdataF, - AMP, frame, slot, fp, cfg, - &gNB->dlsch_encoding_stats, - &gNB->dlsch_scrambling_stats, - &gNB->dlsch_modulation_stats); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0); - } - } + nr_generate_dci_top(gNB->pdcch_vars.dci_alloc[i], + gNB->nr_gold_pdcch_dmrs[slot], + &gNB->common_vars.txdataF[0][txdataF_offset], // hardcoded to beam 0 + AMP, *fp, *cfg); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0); + } + + for (int i=0; idlsch[i][0], + &gNB->pdcch_vars.dci_alloc[i], + gNB->nr_gold_pdsch_dmrs[slot], + gNB->common_vars.txdataF, + AMP, frame, slot, fp, cfg, + &gNB->dlsch_encoding_stats, + &gNB->dlsch_scrambling_stats, + &gNB->dlsch_modulation_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,0); @@ -219,10 +217,10 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id, uint8_t harq_pid) { NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu; + nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu; nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &rel15_ul->ulsch_pdu_rel15; - //uint8_t ret; + uint8_t ret; uint32_t G; int Nid_cell = 0; // [hna] shouldn't be a local variable (should be signaled) @@ -247,8 +245,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id //--------------------- ULSCH decoding --------------------- //---------------------------------------------------------- - //ret = nr_ulsch_decoding(gNB, - nr_ulsch_decoding(gNB, + ret = nr_ulsch_decoding(gNB, UE_id, gNB->pusch_vars[UE_id]->llr, frame_parms, @@ -258,8 +255,10 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id harq_pid, 0); - // if (ret > ulsch_gNB->max_ldpc_iterations) - // n_errors++; + if (ret > gNB->ulsch[UE_id][0]->max_ldpc_iterations) + LOG_I(PHY, "ULSCH in error\n"); + else + LOG_I(PHY, "ULSCH received ok\n"); } @@ -302,6 +301,7 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, // case 75: timing_advance_update /= 12; break; case 106: timing_advance_update /= 16; break; case 217: timing_advance_update /= 32; break; + case 273: timing_advance_update /= 32; break; default: abort(); } @@ -351,19 +351,36 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } +void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { -void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, uint8_t symbol_start, uint8_t symbol_end) { + nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req; + int num_pusch_pdu = UL_tti_req->n_pdus; + + LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d, num_pusch_pdu %d\n",frame_rx,slot_rx,num_pusch_pdu); - uint8_t UE_id; - uint8_t symbol; - uint8_t harq_pid = 0; // [hna] Previously in LTE, the harq_pid was obtained from the subframe number (Synchronous HARQ) - // In NR, this should be signaled through uplink scheduling dci (i.e, DCI 0_0, 0_1) (Asynchronous HARQ) + for (int i = 0; i < num_pusch_pdu; i++) { - for (UE_id = 0; UE_id < 1; UE_id++) { // temporary set to 1 untill list of connected UEs is implemented - for(symbol = symbol_start; symbol < symbol_end; symbol++) { - nr_rx_pusch(gNB, UE_id, frame_rx, slot_rx, symbol, harq_pid); + switch (UL_tti_req->pdus_list[i].pdu_type) { + case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: + { + LOG_I(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE\n",frame_rx,slot_rx); + + nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; + nr_fill_ulsch(gNB,frame_rx,slot_rx,pusch_pdu); + + uint8_t UE_id = find_nr_ulsch(pusch_pdu->rnti,gNB,SEARCH_EXIST); + uint8_t harq_pid = pusch_pdu->pusch_data.harq_process_id; + uint8_t symbol_start = pusch_pdu->start_symbol_index; + uint8_t symbol_end = symbol_start + pusch_pdu->nr_of_symbols; + + for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) { + nr_rx_pusch(gNB, UE_id, frame_rx, slot_rx, symbol, harq_pid); + } + //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[UE_id]->rxdataF_comp[0],6900,1,1); + //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[UE_id]->rxdataF_ext[0],6900,1,1); + nr_ulsch_procedures(gNB, frame_rx, slot_rx, UE_id, harq_pid); + nr_fill_rx_indication(gNB, frame_rx, slot_rx, UE_id, harq_pid); // indicate SDU to MAC + } } - nr_ulsch_procedures(gNB, frame_rx, slot_rx, UE_id, harq_pid); - nr_fill_rx_indication(gNB, frame_rx, slot_rx, UE_id, harq_pid); // indicate SDU to MAC } } diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 778008fe99..af611a6296 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -38,7 +38,7 @@ nr_slot_t nr_slot_select (nfapi_nr_config_request_t *cfg, unsigned char slot); void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp); void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_meas); void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); -void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, uint8_t symbol_start, uint8_t symbol_end); +void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot); void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx); diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 4635f6fb49..8e42149add 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -370,7 +370,7 @@ void nr_compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsP void set_tx_harq_id(NR_UE_ULSCH_t *ulsch, int harq_pid, int slot_tx); int get_tx_harq_id(NR_UE_ULSCH_t *ulsch, int slot_tx); - +int is_pbch_in_slot(fapi_nr_pbch_config_t *pbch_config, int frame, int slot, int periodicity, uint16_t slots_per_frame); /*@}*/ diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 999a2fe5d3..1bd7071b99 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -123,6 +123,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id; dlsch0_harq->harq_ack.slot_for_feedback_ack = dlsch_config_pdu->pdsch_to_harq_feedback_time_ind; dlsch0_harq->Nl=1; + dlsch0_harq->mcs_table=0; dlsch0_harq->status = ACTIVE; LOG_D(MAC,">>>> \tdlsch0->g_pucch=%d\tdlsch0_harq.mcs=%d\n",dlsch0->g_pucch,dlsch0_harq->mcs); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index ccf534353d..60378d81fc 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -3307,7 +3307,7 @@ void copy_harq_proc_struct(NR_DL_UE_HARQ_t *harq_processes_dest, NR_DL_UE_HARQ_t harq_processes_dest->B = current_harq_processes->B ; harq_processes_dest->C = current_harq_processes->C ; - harq_processes_dest->DCINdi = current_harq_processes->DCINdi ; + harq_processes_dest->DCINdi = current_harq_processes->DCINdi ; harq_processes_dest->F = current_harq_processes->F ; harq_processes_dest->G = current_harq_processes->G ; harq_processes_dest->K = current_harq_processes->K ; @@ -3320,6 +3320,7 @@ void copy_harq_proc_struct(NR_DL_UE_HARQ_t *harq_processes_dest, NR_DL_UE_HARQ_t harq_processes_dest->dl_power_off = current_harq_processes->dl_power_off ; harq_processes_dest->first_tx = current_harq_processes->first_tx ; harq_processes_dest->mcs = current_harq_processes->mcs ; + harq_processes_dest->mcs_table = current_harq_processes->mcs_table ; harq_processes_dest->mimo_mode = current_harq_processes->mimo_mode ; harq_processes_dest->nb_rb = current_harq_processes->nb_rb ; harq_processes_dest->pmi_alloc = current_harq_processes->pmi_alloc ; @@ -4139,6 +4140,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, uint8_t harq_pid = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid; NR_DL_UE_HARQ_t *dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; uint16_t nb_symb_sch = dlsch0_harq->nb_symbols; + uint16_t start_symb_sch = dlsch0_harq->start_symbol; uint8_t nb_symb_pdcch = pdcch_vars->coreset[0].duration; uint8_t ssb_periodicity = 10;// ue->ssb_periodicity; // initialized to 5ms in nr_init_ue for scenarios where UE is not configured (otherwise acquired by cell configuration from gNB or LTE) uint8_t dci_cnt = 0; @@ -4165,6 +4167,43 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, } uint16_t coreset_nb_rb = 6 * coreset_count; uint16_t coreset_start_rb = 6 * coreset_start; + + slot_pbch = is_pbch_in_slot(pbch_config, frame_rx, nr_tti_rx, ssb_periodicity, ue->frame_parms.slots_per_frame); + + // looking for pbch only in slot where it is supposed to be + if ((ue->decode_MIB == 1) && slot_pbch) + { + LOG_I(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); + + for (int i=1; i<4; i++) { + + nr_slot_fep(ue, + (ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot), + nr_tti_rx, + 0, + 0); + +#if UE_TIMING_TRACE + start_meas(&ue->dlsch_channel_estimation_stats); +#endif + nr_pbch_channel_estimation(ue,0,nr_tti_rx,(ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot),i-1,(pbch_config->ssb_index)&7,pbch_config->half_frame_bit); +#if UE_TIMING_TRACE + stop_meas(&ue->dlsch_channel_estimation_stats); +#endif + + } + nr_ue_pbch_procedures(eNB_id,ue,proc,0); + + if (ue->no_timing_correction==0) { + LOG_I(PHY,"start adjust sync slot = %d no timing %d\n", nr_tti_rx, ue->no_timing_correction); + nr_adjust_synch_ue(&ue->frame_parms, + ue, + eNB_id, + nr_tti_rx, + 0, + 16384); + } + } #ifdef NR_PDCCH_SCHED nr_gold_pdcch(ue, 0, 2); @@ -4204,16 +4243,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if (dci_cnt > 0) { LOG_I(PHY,"[UE %d] Frame %d, nr_tti_rx %d: found %d DCIs\n",ue->Mod_id,frame_rx,nr_tti_rx,dci_cnt); - - if (ue->no_timing_correction==0) { - LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_tti_rx, ue->no_timing_correction); - nr_adjust_synch_ue(&ue->frame_parms, - ue, - eNB_id, - nr_tti_rx, - 0, - 16384); - } + } else { LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: No DCIs found\n",ue->Mod_id,frame_rx,nr_tti_rx); } @@ -4223,11 +4253,12 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if (dci_cnt > 0){ LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); //to update from pdsch config - nr_gold_pdsch(ue,nb_symb_pdcch,0, 1); + start_symb_sch = dlsch0_harq->start_symbol; + nr_gold_pdsch(ue,start_symb_sch,0, 1); nb_symb_sch = dlsch0_harq->nb_symbols; - for (uint16_t m=nb_symb_pdcch;m<=(nb_symb_sch+nb_symb_pdcch-1) ; m++){ + for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){ nr_slot_fep(ue, m, //to be updated from higher layer nr_tti_rx, @@ -4308,34 +4339,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); } - - slot_pbch = is_pbch_in_slot(pbch_config, frame_rx, nr_tti_rx, ssb_periodicity, ue->frame_parms.slots_per_frame); - - // looking for pbch only in slot where it is supposed to be - if ((ue->decode_MIB == 1) && slot_pbch) - { - LOG_I(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); - - for (int i=1; i<4; i++) { - - nr_slot_fep(ue, - (ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot), - nr_tti_rx, - 0, - 0); - -#if UE_TIMING_TRACE - start_meas(&ue->dlsch_channel_estimation_stats); -#endif - nr_pbch_channel_estimation(ue,0,nr_tti_rx,(ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot),i-1,(pbch_config->ssb_index)&7,pbch_config->half_frame_bit); -#if UE_TIMING_TRACE - stop_meas(&ue->dlsch_channel_estimation_stats); -#endif - - } - nr_ue_pbch_procedures(eNB_id,ue,proc,0); - } - + // do procedures for C-RNTI if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) { diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index b07fdad73a..aab762b9e2 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -110,6 +110,7 @@ int main(int argc, char **argv) uint16_t nb_symb_sch = 12; uint16_t nb_rb = 50; uint8_t Imcs = 9; + uint8_t mcs_table = 0; cpuf = get_cpu_freq_GHz(); @@ -430,6 +431,7 @@ int main(int argc, char **argv) uint8_t nb_re_dmrs = 6; uint16_t length_dmrs = 1; unsigned char mod_order; + uint16_t rate; uint8_t Nl = 1; uint8_t rvidx = 0; dlsch->rnti = 1; @@ -437,9 +439,10 @@ int main(int argc, char **argv) dlsch->harq_processes[0]->rvidx = rvidx;*/ //printf("dlschsim harqid %d nb_rb %d, mscs %d\n",dlsch->harq_ids[subframe], // dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->mcs,dlsch->harq_processes[0]->Nl); - mod_order = nr_get_Qm(Imcs, 1); + mod_order = nr_get_Qm_dl(Imcs, mcs_table); + rate = nr_get_code_rate_dl(Imcs, mcs_table); available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); - TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl); + TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, Nl); printf("available bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order); //dlsch->harq_ids[subframe]= 0; rel15->n_prb = nb_rb; @@ -448,6 +451,7 @@ int main(int argc, char **argv) rel15->nb_layers = Nl; rel15->nb_re_dmrs = nb_re_dmrs; rel15->transport_block_size = TBS; + rel15->coding_rate = rate; double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384); short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384); @@ -462,10 +466,12 @@ int main(int argc, char **argv) NR_UE_DLSCH_t *dlsch0_ue = UE->dlsch[0][0][0]; NR_DL_UE_HARQ_t *harq_process = dlsch0_ue->harq_processes[harq_pid]; harq_process->mcs = Imcs; + harq_process->mcs_table = mcs_table; harq_process->Nl = Nl; harq_process->nb_rb = nb_rb; harq_process->Qm = mod_order; harq_process->rvidx = rvidx; + harq_process->R = rate; printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch); unsigned char *test_input; test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index e203b5dc48..99c413f376 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -75,31 +75,29 @@ void config_common(int Mod_idP,int CC_idP,int Nid_cell,int nr_bandP,uint64_t SSB int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return(0);} uint64_t get_softmodem_optmask(void) {return 0;} -mac_rlc_status_resp_t mac_rlc_status_ind( const module_id_t module_idP, const rnti_t rntiP, - const eNB_index_t eNB_index, const frame_t frameP, - const sub_frame_t subframeP, const eNB_flag_t enb_flagP, - const MBMS_flag_t MBMS_flagP, const logical_chan_id_t channel_idP, - const tb_size_t tb_sizeP - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,const uint32_t sourceL2Id - ,const uint32_t destinationL2Id - #endif - ){mac_rlc_status_resp_t mac_rlc_status_resp; return mac_rlc_status_resp;} -tbs_size_t mac_rlc_data_req( - const module_id_t module_idP, - const rnti_t rntiP, - const eNB_index_t eNB_index, - const frame_t frameP, - const eNB_flag_t enb_flagP, - const MBMS_flag_t MBMS_flagP, - const logical_chan_id_t channel_idP, - const tb_size_t tb_sizeP, - char *buffer_pP -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,const uint32_t sourceL2Id - ,const uint32_t destinationL2Id -#endif - ) +mac_rlc_status_resp_t mac_rlc_status_ind( const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const sub_frame_t subframeP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + const tb_size_t tb_sizeP, + const uint32_t sourceL2Id, + const uint32_t destinationL2Id) +{mac_rlc_status_resp_t mac_rlc_status_resp; return mac_rlc_status_resp;} +tbs_size_t mac_rlc_data_req( const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + const tb_size_t tb_sizeP, + char *buffer_pP, + const uint32_t sourceL2Id, + const uint32_t destinationL2Id ) {return 0;} int generate_dlsch_header(unsigned char *mac_header, unsigned char num_sdus, @@ -167,6 +165,12 @@ int main(int argc, char **argv) //double pbch_sinr; //int pbch_tx_ant; int N_RB_DL=106,mu=1; + nfapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config; + dlsch_config.start_prb = 0; + dlsch_config.n_prb = 50; + dlsch_config.start_symbol = 2; + dlsch_config.nb_symbols = 9; + dlsch_config.mcs_idx = 9; uint16_t ssb_periodicity = 10; @@ -188,6 +192,7 @@ int main(int argc, char **argv) int run_initial_sync=0; int do_pdcch_flag=1; + uint16_t cset_offset = 0; int loglvl=OAILOG_WARNING; float target_error_rate = 0.01; @@ -200,7 +205,7 @@ int main(int argc, char **argv) randominit(0); - while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dP:IL:")) != -1) { + while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dP:IL:o:a:b:c:j:e:")) != -1) { switch (c) { /*case 'f': write_output_file=1; @@ -365,6 +370,30 @@ int main(int argc, char **argv) loglvl = atoi(optarg); break; + case 'o': + cset_offset = atoi(optarg); + break; + + case 'a': + dlsch_config.start_prb = atoi(optarg); + break; + + case 'b': + dlsch_config.n_prb = atoi(optarg); + break; + + case 'c': + dlsch_config.start_symbol = atoi(optarg); + break; + + case 'j': + dlsch_config.nb_symbols = atoi(optarg); + break; + + case 'e': + dlsch_config.mcs_idx = atoi(optarg); + break; + default: case 'h': printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", @@ -390,6 +419,12 @@ int main(int argc, char **argv) //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); //printf("-f Output filename (.txt format) for Pe/SNR results\n"); printf("-F Input filename (.txt format) for RX conformance testing\n"); + printf("-o CORESET offset\n"); + printf("-a Start PRB for PDSCH\n"); + printf("-b Number of PRB for PDSCH\n"); + printf("-c Start symbol for PDSCH (fixed for now)\n"); + printf("-j Number of symbols for PDSCH (fixed for now)\n"); + printf("-e MSC index\n"); exit (-1); break; } @@ -482,7 +517,7 @@ int main(int argc, char **argv) printf("Allocating %d samples for txdata\n",frame_length_complex_samples); txdata[i] = malloc(frame_length_complex_samples*sizeof(int)); - bzero(r_re[i],frame_length_complex_samples*sizeof(int)); + bzero(txdata[i],frame_length_complex_samples*sizeof(int)); } @@ -546,18 +581,20 @@ int main(int argc, char **argv) test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); + uint16_t rb_offset_count = cset_offset/6; + set_cset_offset(rb_offset_count); // generate signal if (input_fd==NULL) { gNB->pbch_configured = 1; for (int i=0;i<4;i++) gNB->pbch_pdu[i]=i+1; - nr_schedule_uss_dlsch_phytest(0,frame,slot); + nr_schedule_uss_dlsch_phytest(0,frame,slot,&dlsch_config); Sched_INFO.module_id = 0; Sched_INFO.CC_id = 0; Sched_INFO.frame = frame; Sched_INFO.slot = slot; Sched_INFO.DL_req = &gNB_mac->DL_req[0]; - Sched_INFO.UL_req = NULL; + Sched_INFO.UL_tti_req = &gNB_mac->UL_tti_req[0]; Sched_INFO.HI_DCI0_req = NULL; Sched_INFO.TX_req = &gNB_mac->TX_req[0]; nr_schedule_response(&Sched_INFO); @@ -646,13 +683,15 @@ int main(int argc, char **argv) uint64_t mask = 0x0; uint16_t num_rbs=24; - uint16_t rb_offset=0; + uint16_t rb_offset=gNB->pdcch_vars.dci_alloc[0].pdcch_params.rb_offset; uint16_t cell_id=0; uint16_t num_symbols=2; for(i=0; i<(num_rbs/6); ++i){ // 38.331 Each bit corresponds a group of 6 RBs mask = mask >> 1; mask = mask | 0x100000000000; } + uint16_t UE_rb_offset_count = rb_offset/6; + mask = mask >> UE_rb_offset_count; dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.frequency_domain_resource = mask; dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.rb_offset = rb_offset; // additional parameter other than coreset @@ -663,8 +702,6 @@ int main(int argc, char **argv) dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_shift_index = cell_id; dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.precoder_granularity = PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE; dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.pdcch_dmrs_scrambling_id = cell_id; - uint8_t gnb_start_symbol = Sched_INFO.DL_req->dl_config_request_body.dl_config_pdu_list[1].dlsch_pdu.dlsch_pdu_rel15.start_symbol; - dl_config->dl_config_list[0].dlsch_config_pdu.dlsch_config_rel15.start_symbol = gnb_start_symbol; uint32_t number_of_search_space_per_slot=1; uint32_t first_symbol_index=0; @@ -842,25 +879,17 @@ int main(int argc, char **argv) printf("*****************************************\n"); printf("SNR %f, (false positive %f)\n", SNR, - (float) n_false_positive / (float) n_trials); + (float) n_errors / (float) n_trials); printf("*****************************************\n"); printf("\n"); - if (errors_bit == 0) { - printf("PDSCH test OK\n"); - printf("\n"); - } - printf("SNR %f : n_errors (negative CRC) = %d/%d\n", SNR, n_errors, n_trials); printf("\n"); if ((float)n_errors/(float)n_trials <= target_error_rate) { - printf("PDCCH test OK\n"); + printf("PDSCH test OK\n"); break; } - - if (n_trials == 1) - break; } // NSR diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index b828cbdf11..07105e6e1f 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -375,20 +375,21 @@ int main(int argc, char **argv) uint8_t nb_re_dmrs = 6; uint8_t length_dmrs = 1; uint8_t N_PRB_oh; - uint16_t N_RE_prime; + uint16_t N_RE_prime,code_rate; unsigned char mod_order; uint8_t Nl = 1; uint8_t rvidx = 0; uint8_t UE_id = 0; - NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id+1][0]; + NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0]; nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15; NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0][0]; - mod_order = nr_get_Qm(Imcs, 1); + mod_order = nr_get_Qm_ul(Imcs, 0); + code_rate = nr_get_code_rate_ul(Imcs, 0); available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); - TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl); + TBS = nr_compute_tbs(mod_order,code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, Nl); printf("\nAvailable bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order); @@ -401,6 +402,7 @@ int main(int argc, char **argv) rel15_ul->n_layers = Nl; rel15_ul->nb_re_dmrs = nb_re_dmrs; rel15_ul->length_dmrs = length_dmrs; + rel15_ul->R = code_rate; /////////////////////////////////////////////////// double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc @@ -563,31 +565,6 @@ int main(int argc, char **argv) printf("\n"); } - for (i = 0; i < 2; i++) { - - printf("----------------------\n"); - printf("freeing codeword %d\n", i); - printf("----------------------\n"); - - printf("gNB ulsch[0][%d]\n", i); // [hna] ulsch[0] is for RA - - free_gNB_ulsch(gNB->ulsch[0][i]); - - printf("gNB ulsch[%d][%d]\n",UE_id+1, i); - - free_gNB_ulsch(gNB->ulsch[UE_id+1][i]); - - for (sf = 0; sf < 2; sf++) { - - printf("UE ulsch[%d][0][%d]\n", sf, i); - - if (UE->ulsch[sf][0][i]) - free_nr_ue_ulsch(UE->ulsch[sf][0][i]); - } - - printf("\n"); - } - if (output_fd) fclose(output_fd); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 00ba0bbc45..15e7d3ca0e 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -54,6 +54,7 @@ #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" #include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" +#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" //#define DEBUG_ULSIM @@ -69,19 +70,50 @@ uint16_t NB_UE_INST = 1; // dummy functions int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) { return 0; } -void mac_rlc_data_ind ( - const module_id_t module_idP, - const rnti_t rntiP, - const eNB_index_t eNB_index, - const frame_t frameP, - const eNB_flag_t enb_flagP, - const MBMS_flag_t MBMS_flagP, - const logical_chan_id_t channel_idP, - char *buffer_pP, - const tb_size_t tb_sizeP, - num_tb_t num_tbP, - crc_t *crcs_pP) -{} +void mac_rlc_data_ind ( const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + char *buffer_pP, + const tb_size_t tb_sizeP, + num_tb_t num_tbP, + crc_t *crcs_pP){} +mac_rlc_status_resp_t mac_rlc_status_ind( const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const sub_frame_t subframeP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + const tb_size_t tb_sizeP, + const uint32_t sourceL2Id, + const uint32_t destinationL2Id) +{mac_rlc_status_resp_t mac_rlc_status_resp; return mac_rlc_status_resp;} +tbs_size_t mac_rlc_data_req( const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + const tb_size_t tb_sizeP, + char *buffer_pP, + const uint32_t sourceL2Id, + const uint32_t destinationL2Id ) +{return 0;} +int generate_dlsch_header(unsigned char *mac_header, + unsigned char num_sdus, + unsigned short *sdu_lengths, + unsigned char *sdu_lcids, + unsigned char drx_cmd, + unsigned short timing_advance_cmd, + unsigned char *ue_cont_res_id, + unsigned char short_padding, + unsigned short post_padding){return 0;} uint64_t get_softmodem_optmask(void) {return 0;} int rlc_module_init (void) {return(0);} void pdcp_layer_init (void) {} @@ -114,7 +146,7 @@ int main(int argc, char **argv) uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; //unsigned char frame_type = 0; int number_of_frames = 1; - int frame_length_complex_samples; + int frame_length_complex_samples, frame_length_complex_samples_no_prefix ; NR_DL_FRAME_PARMS *frame_parms; int loglvl = OAILOG_WARNING; uint64_t SSB_positions=0x01; @@ -144,7 +176,7 @@ int main(int argc, char **argv) //logInit(); randominit(0); - while ((c = getopt(argc, argv, "d:f:g:h:i:j:l:m:n:p:r:s:y:z:F:M:N:P:R:S:")) != -1) { + while ((c = getopt(argc, argv, "d:f:g:h:i:j:l:m:n:p:r:s:y:z:F:M:N:P:R:S:L:")) != -1) { switch (c) { /*case 'd': @@ -303,6 +335,10 @@ int main(int argc, char **argv) printf("Setting SNR1 to %f\n", snr1); break; + case 'L': + loglvl = atoi(optarg); + break; + default: case 'h': printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]); @@ -373,7 +409,7 @@ int main(int argc, char **argv) //init_eNB_afterRU(); frame_length_complex_samples = frame_parms->samples_per_subframe; - //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; + frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; //configure UE UE = malloc(sizeof(PHY_VARS_NR_UE)); @@ -410,14 +446,18 @@ int main(int argc, char **argv) uint8_t nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4; uint8_t length_dmrs = 1; unsigned char mod_order; + uint16_t code_rate; - mod_order = nr_get_Qm(Imcs, 1); + mod_order = nr_get_Qm_ul(Imcs, 0); + code_rate = nr_get_code_rate_ul(Imcs, 0); available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); - TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, precod_nbr_layers); + TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, precod_nbr_layers); + + NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0]; + //nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu; + nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req; + nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; - NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id+1][0]; - nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu; - NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0]; unsigned char *estimated_output_bit; @@ -446,7 +486,8 @@ int main(int argc, char **argv) UE_proc.nr_tti_tx = slot; UE_proc.frame_tx = frame; - // --------- setting rel15_ul parameters for gNB -------- + // --------- setting parameters for gNB -------- + /* rel15_ul->rnti = n_rnti; rel15_ul->ulsch_pdu_rel15.start_rb = start_rb; rel15_ul->ulsch_pdu_rel15.number_rbs = nb_rb; @@ -459,9 +500,52 @@ int main(int argc, char **argv) rel15_ul->ulsch_pdu_rel15.rv = 0; rel15_ul->ulsch_pdu_rel15.ndi = 0; rel15_ul->ulsch_pdu_rel15.n_layers = precod_nbr_layers; + rel15_ul->ulsch_pdu_rel15.R = code_rate; /////////////////////////////////////////////////// + */ - //fapi_nr_tx_request_t tx_request; + UL_tti_req->sfn = frame; + UL_tti_req->slot = slot; + UL_tti_req->n_pdus = 1; + UL_tti_req->pdus_list[0].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; + UL_tti_req->pdus_list[0].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); + memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t)); + + pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; + pusch_pdu->rnti = n_rnti; + pusch_pdu->mcs_index = Imcs; + pusch_pdu->mcs_table = 0; + pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); + pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; + pusch_pdu->transform_precoding = 0; + pusch_pdu->data_scrambling_id = 0; + pusch_pdu->nrOfLayers = 1; + pusch_pdu->ul_dmrs_symb_pos = 1; + pusch_pdu->dmrs_config_type = 0; + pusch_pdu->ul_dmrs_scrambling_id = 0; + pusch_pdu->scid = 0; + pusch_pdu->resource_alloc = 1; + pusch_pdu->rb_start = start_rb; + pusch_pdu->rb_size = nb_rb; + pusch_pdu->vrb_to_prb_mapping = 0; + pusch_pdu->frequency_hopping = 0; + pusch_pdu->uplink_frequency_shift_7p5khz = 0; + pusch_pdu->start_symbol_index = start_symbol; + pusch_pdu->nr_of_symbols = nb_symb_sch; + pusch_pdu->pusch_data.rv_index = 0; + pusch_pdu->pusch_data.harq_process_id = 0; + pusch_pdu->pusch_data.new_data_indicator = 0; + pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->mcs_index, + pusch_pdu->target_code_rate, + pusch_pdu->rb_size, + pusch_pdu->nr_of_symbols, + nb_re_dmrs*length_dmrs, + 0, + pusch_pdu->nrOfLayers = 1); + pusch_pdu->pusch_data.num_cb = 0; + + + // --------- setting parameters for UE -------- scheduled_response.module_id = 0; scheduled_response.CC_id = 0; @@ -495,6 +579,8 @@ int main(int argc, char **argv) phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id, 0); + //LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_length_complex_samples,1,1); + /////////// //////////////////////////////////////////////////// tx_offset = slot*frame_parms->samples_per_slot; @@ -532,7 +618,9 @@ int main(int argc, char **argv) //---------------------------------------------------------- phy_procedures_gNB_common_RX(gNB, frame, slot); - phy_procedures_gNB_uespec_RX(gNB, frame, slot, rel15_ul->ulsch_pdu_rel15.start_symbol, rel15_ul->ulsch_pdu_rel15.start_symbol + rel15_ul->ulsch_pdu_rel15.number_symbols); + //LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0],frame_length_complex_samples_no_prefix,1,1); + + phy_procedures_gNB_uespec_RX(gNB, frame, slot); //////////////////////////////////////////////////////////// //---------------------------------------------------------- @@ -557,7 +645,7 @@ int main(int argc, char **argv) for (i = 0; i < TBS; i++) { estimated_output_bit[i] = (ulsch_gNB->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7); - test_input_bit[i] = (ulsch_ue[0]->harq_processes[harq_pid]->b[i / 8] & (1 << (i & 7))) >> (i & 7); + test_input_bit[i] = (ulsch_ue[0]->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7); if (estimated_output_bit[i] != test_input_bit[i]) { if(errors_decoding == 0) @@ -581,7 +669,7 @@ int main(int argc, char **argv) break; } // frame loop - if(is_frame_in_error == 0) + if(is_frame_in_error == 0 || number_of_frames==1) break; } // SNR loop @@ -594,31 +682,6 @@ int main(int argc, char **argv) printf("\n"); - for (i = 0; i < 2; i++) { - - printf("----------------------\n"); - printf("freeing codeword %d\n", i); - printf("----------------------\n"); - - printf("gNB ulsch[0][%d]\n", i); // [hna] ulsch[0] is for RA - - free_gNB_ulsch(gNB->ulsch[0][i]); - - printf("gNB ulsch[%d][%d]\n",UE_id+1, i); - - free_gNB_ulsch(gNB->ulsch[UE_id+1][i]); // "+1" because first element in ulsch is for RA - - for (sf = 0; sf < 2; sf++) { - - printf("UE ulsch[%d][0][%d]\n", sf, i); - - if (UE->ulsch[sf][0][i]) - free_nr_ue_ulsch(UE->ulsch[sf][0][i]); - } - - printf("\n"); - } - free(test_input_bit); free(estimated_output_bit); diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index 477949a296..ec257f5ceb 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -96,8 +96,8 @@ #define MAX_gNB 2 #endif -#define NUMBER_OF_NR_DLSCH_MAX 16 -#define NUMBER_OF_NR_ULSCH_MAX 16 +#define NUMBER_OF_NR_DLSCH_MAX 4 +#define NUMBER_OF_NR_ULSCH_MAX 4 #define MAX_MANAGED_ENB_PER_MOBILE 2 #define MAX_MANAGED_GNB_PER_MOBILE 2 diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 1a243b0aa4..6b9e79d510 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -226,7 +226,7 @@ int8_t nr_ue_decode_mib( uint32_t ssb_length, uint32_t ssb_index, void *pduP, - uint16_t cell_id ){ + uint16_t cell_id ){ LOG_I(MAC,"[L2][MAC] decode mib\n"); @@ -283,7 +283,7 @@ int8_t nr_ue_decode_mib( scs_pdcch = scs_30kHz; } - channel_bandwidth_t min_channel_bw = bw_40MHz; // deafult for testing + channel_bandwidth_t min_channel_bw = bw_10MHz; // deafult for testing uint32_t is_condition_A = (ssb_subcarrier_offset == 0); // 38.213 ch.13 frequency_range_t frequency_range = FR1; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 635220b6e9..e43f2633b1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -76,7 +76,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, sub_frame_t slotP){ nfapi_nr_dl_config_request_t *DL_req = &gNB->DL_req[0]; - nfapi_ul_config_request_t *UL_req = &gNB->UL_req[0]; + nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req[0]; nfapi_hi_dci0_request_t * HI_DCI0_req = &gNB->HI_DCI0_req[0]; nfapi_tx_request_t *TX_req = &gNB->TX_req[0]; @@ -93,9 +93,10 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci = 0; - UL_req[CC_idP].ul_config_request_body.number_of_pdus = 0; - UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources = 0; // ignored, handled by PHY for now - UL_req[CC_idP].ul_config_request_body.srs_present = 0; // ignored, handled by PHY for now + UL_tti_req[CC_idP].n_pdus = 0; + UL_tti_req[CC_idP].n_ulsch = 0; + UL_tti_req[CC_idP].n_ulcch = 0; + UL_tti_req[CC_idP].n_group = 0; TX_req[CC_idP].tx_request_body.number_of_pdus = 0; @@ -261,6 +262,8 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram } } */ + +/* void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { int CC_id; @@ -289,10 +292,14 @@ void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ul_req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t)); } } +*/ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, - frame_t frameP, - sub_frame_t slotP){ + frame_t frame_rxP, + sub_frame_t slot_rxP, + frame_t frame_txP, + sub_frame_t slot_txP){ + protocol_ctxt_t ctxt; int CC_id, i = -1; @@ -300,12 +307,13 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, rnti_t rnti; NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels; + //nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = NULL; start_meas(&RC.nrmac[module_idP]->eNB_scheduler); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN); - RC.nrmac[module_idP]->frame = frameP; - RC.nrmac[module_idP]->slot = slotP; + RC.nrmac[module_idP]->frame = frame_rxP; + RC.nrmac[module_idP]->slot = slot_rxP; for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { @@ -315,12 +323,12 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, memset(cc[CC_id].vrb_map, 0, 100); memset(cc[CC_id].vrb_map_UL, 0, 100); - clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frameP, slotP); + clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame_txP, slot_txP); } // refresh UE list based on UEs dropped by PHY in previous subframe for (i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (UE_list->active[i]) { + if (0 /*UE_list->active[i]*/) { nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id]; @@ -329,17 +337,17 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, if (nr_is_dci_opportunity(search_space, coreset, - frameP, - slotP, + frame_txP, + slot_txP, *cfg)){ - nr_schedule_uss_dlsch_phytest(module_idP, frameP, slotP); + nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP, NULL); } rnti = UE_RNTI(module_idP, i); CC_id = UE_PCCID(module_idP, i); //int spf = get_spf(cfg); - - if (((frameP&127) == 0) && (slotP == 0)) { + + if (((frame_txP&127) == 0) && (slot_txP == 0)) { LOG_I(MAC, "UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", rnti, @@ -350,107 +358,38 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, (UE_list->UE_sched_ctrl[i].pusch_snr[CC_id] - 128) / 2, (UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id] - 128) / 2); } - - RC.gNB[module_idP][CC_id]->pusch_stats_bsr[i][to_absslot(cfg,frameP,slotP)] = -63; - - if (i == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,RC.gNB[module_idP][CC_id]-> - pusch_stats_bsr[i][to_absslot(cfg,frameP,slotP)]); - - // increment this, it is cleared when we receive an sdu - RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++; - RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++; - - LOG_D(MAC, "UE %d/%x : ul_inactivity %d, cqi_req %d\n", - i, - rnti, - RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer, - RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer); - - //check_nr_ul_failure(module_idP, CC_id, i, frameP, subframeP); - - if (RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer > 0) { - RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer++; - - if(RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer >= - RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer_thres) { - RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer = 0; - - for (int ue_id_l = 0; ue_id_l < MAX_MOBILES_PER_GNB; ue_id_l++) { - if (reestablish_rnti_map[ue_id_l][0] == rnti) { - // clear currentC-RNTI from map - reestablish_rnti_map[ue_id_l][0] = 0; - reestablish_rnti_map[ue_id_l][1] = 0; - break; - } - } - - // Note: This should not be done in the MAC! - for (int ii=0; iiulsch[ii][0]; - if((ulsch != NULL) && (ulsch->rnti == rnti)){ - LOG_W(MAC, "TODO: clean_eNb_ulsch UE %x \n", rnti); - clean_gNB_ulsch(ulsch); - } - } - - for (int ii=0; iidlsch[ii][0]; - if((dlsch != NULL) && (dlsch->rnti == rnti)){ - LOG_W(MAC, "TODO: clean_eNb_dlsch UE %x \n", rnti); - clean_gNB_dlsch(dlsch); - } - } - - for(int j = 0; j < 10; j++){ - nfapi_ul_config_request_body_t *ul_req_tmp = NULL; - ul_req_tmp = &RC.nrmac[module_idP]->UL_req_tmp[CC_id][j].ul_config_request_body; - if(ul_req_tmp){ - int pdu_number = ul_req_tmp->number_of_pdus; - for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){ - if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti){ - LOG_I(MAC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number); - if(pdu_index < pdu_number -1){ - memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t)); - } - ul_req_tmp->number_of_pdus--; - } - } - } - } - rrc_mac_remove_ue(module_idP,rnti); - } - } //END if (RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer > 0) + } //END if (UE_list->active[i]) } //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++) - - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES,NOT_A_RNTI, frameP, slotP,module_idP); - + + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES,NOT_A_RNTI, frame_txP, slot_txP,module_idP); + pdcp_run(&ctxt); //rrc_rx_tx(&ctxt, CC_id); // This schedules MIB - if((slotP == 0) && (frameP & 7) == 0){ - schedule_nr_mib(module_idP, frameP, slotP); + if((slot_txP == 0) && (frame_txP & 7) == 0){ + schedule_nr_mib(module_idP, frame_txP, slot_txP); } - // Phytest scheduling/ option not activated because of pending bug - - /*if (slotP==2) - nr_schedule_css_dlsch_phytest(module_idP, frameP, slotP);*/ - - if (slotP==1){ - nr_schedule_uss_dlsch_phytest(module_idP, frameP, slotP); + // Phytest scheduling + + if (slot_rxP==2){ + nr_schedule_uss_ulsch_phytest(&RC.nrmac[module_idP]->UL_tti_req[0], frame_rxP, slot_rxP); + } + + if (slot_txP==1){ + nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP,NULL); } /* // Allocate CCEs for good after scheduling is done for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) allocate_CCEs(module_idP, CC_id, subframeP, 0); - - stop_meas(&RC.nrmac[module_idP]->eNB_scheduler); */ + stop_meas(&RC.nrmac[module_idP]->eNB_scheduler); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 9d04885feb..ea3ee86db1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -41,45 +41,36 @@ extern RAN_CONTEXT_t RC; * current version has only a DCI for type 1 PDCCH for C_RNTI*/ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, frame_t frameP, - sub_frame_t slotP) -{ + sub_frame_t slotP) { uint8_t CC_id; - gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = nr_mac->common_channels; nfapi_nr_dl_config_request_body_t *dl_req; nfapi_nr_dl_config_request_pdu_t *dl_config_dci_pdu; nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu; nfapi_tx_request_pdu_t *TX_req; - nfapi_nr_config_request_t *cfg = &nr_mac->config[0]; uint16_t rnti = 0x1234; - uint16_t sfn_sf = frameP << 7 | slotP; int dl_carrier_bandwidth = cfg->rf_config.dl_carrier_bandwidth.value; - // everything here is hard-coded to 30 kHz int scs = get_dlscs(cfg); int slots_per_frame = get_spf(cfg); + for (CC_id=0; CC_idDL_req[CC_id].dl_config_request_body; dl_config_dci_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_dci_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t)); + memset((void *)dl_config_dci_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t)); dl_config_dci_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_dci_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dci_dl_pdu)); - dl_config_dlsch_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu+1]; - memset((void*)dl_config_dlsch_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t)); + memset((void *)dl_config_dlsch_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t)); dl_config_dlsch_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE; dl_config_dlsch_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dlsch_pdu)); - - nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &dl_config_dci_pdu->dci_dl_pdu.dci_dl_pdu_rel15; + nfapi_nr_dl_config_dci_dl_pdu_rel15_t *dci_dl_pdu_rel15 = &dl_config_dci_pdu->dci_dl_pdu.dci_dl_pdu_rel15; nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &dl_config_dci_pdu->dci_dl_pdu.pdcch_params_rel15; nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu_rel15 = &dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15; - dlsch_pdu_rel15->start_prb = 0; dlsch_pdu_rel15->n_prb = 50; dlsch_pdu_rel15->start_symbol = 2; @@ -90,41 +81,34 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, dlsch_pdu_rel15->mcs_idx = 9; dlsch_pdu_rel15->ndi = 1; dlsch_pdu_rel15->redundancy_version = 0; - - nr_configure_css_dci_initial(params_rel15, - scs, scs, nr_FR1, 0, 0, 0, - sfn_sf, slotP, - slots_per_frame, - dl_carrier_bandwidth); - + scs, scs, nr_FR1, 0, 0, 0, + sfn_sf, slotP, + slots_per_frame, + dl_carrier_bandwidth); params_rel15->first_slot = 0; - - pdu_rel15->frequency_domain_assignment = get_RIV(dlsch_pdu_rel15->start_prb, dlsch_pdu_rel15->n_prb, cfg->rf_config.dl_carrier_bandwidth.value); - pdu_rel15->time_domain_assignment = 3; // row index used here instead of SLIV - pdu_rel15->vrb_to_prb_mapping = 1; - pdu_rel15->mcs = 9; - pdu_rel15->tb_scaling = 1; - - pdu_rel15->ra_preamble_index = 25; - pdu_rel15->format_indicator = 1; - pdu_rel15->ndi = 1; - pdu_rel15->rv = 0; - pdu_rel15->harq_pid = 0; - pdu_rel15->dai = 2; - pdu_rel15->tpc = 2; - pdu_rel15->pucch_resource_indicator = 7; - pdu_rel15->pdsch_to_harq_feedback_timing_indicator = 7; - + dci_dl_pdu_rel15->frequency_domain_assignment = get_RIV(dlsch_pdu_rel15->start_prb, dlsch_pdu_rel15->n_prb, cfg->rf_config.dl_carrier_bandwidth.value); + dci_dl_pdu_rel15->time_domain_assignment = 3; // row index used here instead of SLIV + dci_dl_pdu_rel15->vrb_to_prb_mapping = 1; + dci_dl_pdu_rel15->mcs = 9; + dci_dl_pdu_rel15->tb_scaling = 1; + dci_dl_pdu_rel15->ra_preamble_index = 25; + dci_dl_pdu_rel15->format_indicator = 1; + dci_dl_pdu_rel15->ndi = 1; + dci_dl_pdu_rel15->rv = 0; + dci_dl_pdu_rel15->harq_pid = 0; + dci_dl_pdu_rel15->dai = 2; + dci_dl_pdu_rel15->tpc = 2; + dci_dl_pdu_rel15->pucch_resource_indicator = 7; + dci_dl_pdu_rel15->pdsch_to_harq_feedback_timing_indicator = 7; LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", - pdu_rel15->frequency_domain_assignment, - pdu_rel15->time_domain_assignment, - pdu_rel15->vrb_to_prb_mapping, - pdu_rel15->mcs, - pdu_rel15->tb_scaling, - pdu_rel15->ndi, - pdu_rel15->rv); - + dci_dl_pdu_rel15->frequency_domain_assignment, + dci_dl_pdu_rel15->time_domain_assignment, + dci_dl_pdu_rel15->vrb_to_prb_mapping, + dci_dl_pdu_rel15->mcs, + dci_dl_pdu_rel15->tb_scaling, + dci_dl_pdu_rel15->ndi, + dci_dl_pdu_rel15->rv); params_rel15->rnti = rnti; params_rel15->rnti_type = NFAPI_NR_RNTI_C; params_rel15->dci_format = NFAPI_NR_DL_DCI_FORMAT_1_0; @@ -132,157 +116,148 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, LOG_D(MAC, "DCI type 1 params: rmsi_pdcch_config %d, rnti %d, rnti_type %d, dci_format %d\n \ coreset params: mux_pattern %d, n_rb %d, n_symb %d, rb_offset %d \n \ ss params : nb_ss_sets_per_slot %d, first symb %d, nb_slots %d, sfn_mod2 %d, first slot %d\n", - 0, - params_rel15->rnti, - params_rel15->rnti_type, - params_rel15->dci_format, - params_rel15->mux_pattern, - params_rel15->n_rb, - params_rel15->n_symb, - params_rel15->rb_offset, - params_rel15->nb_ss_sets_per_slot, - params_rel15->first_symbol, - params_rel15->nb_slots, - params_rel15->sfn_mod2, - params_rel15->first_slot); - nr_get_tbs(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg); - LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d\n", - dlsch_pdu_rel15->start_prb, - dlsch_pdu_rel15->n_prb, - dlsch_pdu_rel15->start_symbol, - dlsch_pdu_rel15->nb_symbols, - dlsch_pdu_rel15->nb_layers, - dlsch_pdu_rel15->nb_codewords, - dlsch_pdu_rel15->mcs_idx); - - dl_req->number_dci++; - dl_req->number_pdsch_rnti++; - dl_req->number_pdu+=2; - - TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = 6; - TX_req->pdu_index = nr_mac->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = 8; - TX_req->segments[0].segment_data = &cc[CC_id].RAR_pdu.payload[0]; - nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; - nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; - nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; - + 0, + params_rel15->rnti, + params_rel15->rnti_type, + params_rel15->dci_format, + params_rel15->mux_pattern, + params_rel15->n_rb, + params_rel15->n_symb, + params_rel15->rb_offset, + params_rel15->nb_ss_sets_per_slot, + params_rel15->first_symbol, + params_rel15->nb_slots, + params_rel15->sfn_mod2, + params_rel15->first_slot); + nr_get_tbs_dl(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg); + LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d\n", + dlsch_pdu_rel15->start_prb, + dlsch_pdu_rel15->n_prb, + dlsch_pdu_rel15->start_symbol, + dlsch_pdu_rel15->nb_symbols, + dlsch_pdu_rel15->nb_layers, + dlsch_pdu_rel15->nb_codewords, + dlsch_pdu_rel15->mcs_idx); + dl_req->number_dci++; + dl_req->number_pdsch_rnti++; + dl_req->number_pdu+=2; + TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus]; + TX_req->pdu_length = 6; + TX_req->pdu_index = nr_mac->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = 8; + TX_req->segments[0].segment_data = &cc[CC_id].RAR_pdu.payload[0]; + nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; + nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; + nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; } } int configure_fapi_dl_Tx(nfapi_nr_dl_config_request_body_t *dl_req, - nfapi_tx_request_pdu_t *TX_req, - nfapi_nr_config_request_t *cfg, - nfapi_nr_coreset_t* coreset, - nfapi_nr_search_space_t* search_space, - int16_t pdu_index){ + nfapi_tx_request_pdu_t *TX_req, + nfapi_nr_config_request_t *cfg, + nfapi_nr_coreset_t *coreset, + nfapi_nr_search_space_t *search_space, + int16_t pdu_index, + nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config) { + nfapi_nr_dl_config_request_pdu_t *dl_config_dci_pdu; + nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu; + int TBS; + uint16_t rnti = 0x1234; + int dl_carrier_bandwidth = cfg->rf_config.dl_carrier_bandwidth.value; + dl_config_dci_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *)dl_config_dci_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t)); + dl_config_dci_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_dci_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dci_dl_pdu)); + dl_config_dlsch_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu+1]; + memset((void *)dl_config_dlsch_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t)); + dl_config_dlsch_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_dlsch_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dlsch_pdu)); + nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &dl_config_dci_pdu->dci_dl_pdu.dci_dl_pdu_rel15; + nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &dl_config_dci_pdu->dci_dl_pdu.pdcch_params_rel15; + nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu_rel15 = &dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15; + dlsch_pdu_rel15->start_prb = 0; + dlsch_pdu_rel15->n_prb = 50; + dlsch_pdu_rel15->start_symbol = 2; + dlsch_pdu_rel15->nb_symbols = 9; + dlsch_pdu_rel15->rnti = rnti; + dlsch_pdu_rel15->nb_layers =1; + dlsch_pdu_rel15->nb_codewords = 1; + dlsch_pdu_rel15->mcs_idx = 9; + dlsch_pdu_rel15->ndi = 1; + dlsch_pdu_rel15->redundancy_version = 0; - nfapi_nr_dl_config_request_pdu_t *dl_config_dci_pdu; - nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu; - int TBS; - uint16_t rnti = 0x1234; - int dl_carrier_bandwidth = cfg->rf_config.dl_carrier_bandwidth.value; + if (dlsch_config != NULL) { + dlsch_pdu_rel15->start_prb = dlsch_config->start_prb; + dlsch_pdu_rel15->n_prb = dlsch_config->n_prb; + dlsch_pdu_rel15->start_symbol = dlsch_config->start_symbol; + dlsch_pdu_rel15->nb_symbols = dlsch_config->nb_symbols; + dlsch_pdu_rel15->mcs_idx = dlsch_config->mcs_idx; + } - - dl_config_dci_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_dci_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t)); - dl_config_dci_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_dci_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dci_dl_pdu)); - - dl_config_dlsch_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu+1]; - memset((void*)dl_config_dlsch_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t)); - dl_config_dlsch_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_dlsch_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dlsch_pdu)); - - nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &dl_config_dci_pdu->dci_dl_pdu.dci_dl_pdu_rel15; - nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &dl_config_dci_pdu->dci_dl_pdu.pdcch_params_rel15; - nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu_rel15 = &dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15; - - dlsch_pdu_rel15->start_prb = 0; - dlsch_pdu_rel15->n_prb = 50; - dlsch_pdu_rel15->start_symbol = 2; - dlsch_pdu_rel15->nb_symbols = 9; - dlsch_pdu_rel15->rnti = rnti; - dlsch_pdu_rel15->nb_layers =1; - dlsch_pdu_rel15->nb_codewords = 1; - dlsch_pdu_rel15->mcs_idx = 9; - dlsch_pdu_rel15->ndi = 1; - dlsch_pdu_rel15->redundancy_version = 0; - - nr_configure_dci_from_pdcch_config(params_rel15, - coreset, - search_space, - *cfg, - dl_carrier_bandwidth); - - pdu_rel15->frequency_domain_assignment = get_RIV(dlsch_pdu_rel15->start_prb, dlsch_pdu_rel15->n_prb, cfg->rf_config.dl_carrier_bandwidth.value); - pdu_rel15->time_domain_assignment = 3; // row index used here instead of SLIV; - pdu_rel15->vrb_to_prb_mapping = 1; - pdu_rel15->mcs = 9; - pdu_rel15->tb_scaling = 1; - - pdu_rel15->ra_preamble_index = 25; - pdu_rel15->format_indicator = 1; - pdu_rel15->ndi = 1; - pdu_rel15->rv = 0; - pdu_rel15->harq_pid = 0; - pdu_rel15->dai = 2; - pdu_rel15->tpc = 2; - pdu_rel15->pucch_resource_indicator = 7; - pdu_rel15->pdsch_to_harq_feedback_timing_indicator = 7; - - LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", - pdu_rel15->frequency_domain_assignment, - pdu_rel15->time_domain_assignment, - pdu_rel15->vrb_to_prb_mapping, - pdu_rel15->mcs, - pdu_rel15->tb_scaling, - pdu_rel15->ndi, - pdu_rel15->rv); - - params_rel15->rnti = rnti; - params_rel15->rnti_type = NFAPI_NR_RNTI_C; - params_rel15->dci_format = NFAPI_NR_DL_DCI_FORMAT_1_0; - - //params_rel15->aggregation_level = 1; - LOG_D(MAC, "DCI params: rnti %d, rnti_type %d, dci_format %d, config type %d\n \ + nr_configure_dci_from_pdcch_config(params_rel15, + coreset, + search_space, + *cfg, + dl_carrier_bandwidth); + pdu_rel15->frequency_domain_assignment = get_RIV(dlsch_pdu_rel15->start_prb, dlsch_pdu_rel15->n_prb, cfg->rf_config.dl_carrier_bandwidth.value); + pdu_rel15->time_domain_assignment = 3; // row index used here instead of SLIV; + pdu_rel15->vrb_to_prb_mapping = 1; + pdu_rel15->mcs = dlsch_pdu_rel15->mcs_idx; + pdu_rel15->tb_scaling = 1; + pdu_rel15->ra_preamble_index = 25; + pdu_rel15->format_indicator = 1; + pdu_rel15->ndi = 1; + pdu_rel15->rv = 0; + pdu_rel15->harq_pid = 0; + pdu_rel15->dai = 2; + pdu_rel15->tpc = 2; + pdu_rel15->pucch_resource_indicator = 7; + pdu_rel15->pdsch_to_harq_feedback_timing_indicator = 7; + LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", + pdu_rel15->frequency_domain_assignment, + pdu_rel15->time_domain_assignment, + pdu_rel15->vrb_to_prb_mapping, + pdu_rel15->mcs, + pdu_rel15->tb_scaling, + pdu_rel15->ndi, + pdu_rel15->rv); + params_rel15->rnti = rnti; + params_rel15->rnti_type = NFAPI_NR_RNTI_C; + params_rel15->dci_format = NFAPI_NR_DL_DCI_FORMAT_1_0; + //params_rel15->aggregation_level = 1; + LOG_D(MAC, "DCI params: rnti %d, rnti_type %d, dci_format %d, config type %d\n \ coreset params: mux_pattern %d, n_rb %d, n_symb %d, rb_offset %d \n \ ss params : first symb %d, ss type %d\n", - params_rel15->rnti, - params_rel15->rnti_type, - params_rel15->config_type, - params_rel15->dci_format, - params_rel15->mux_pattern, - params_rel15->n_rb, - params_rel15->n_symb, - params_rel15->rb_offset, - params_rel15->first_symbol, - params_rel15->search_space_type); - nr_get_tbs(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg); - // Hardcode it for now - TBS = dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15.transport_block_size; - LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS: %d\n", - dlsch_pdu_rel15->start_prb, - dlsch_pdu_rel15->n_prb, - dlsch_pdu_rel15->start_symbol, - dlsch_pdu_rel15->nb_symbols, - dlsch_pdu_rel15->nb_layers, - dlsch_pdu_rel15->nb_codewords, - dlsch_pdu_rel15->mcs_idx, - TBS); - - dl_req->number_dci++; - dl_req->number_pdsch_rnti++; - dl_req->number_pdu+=2; - - TX_req->pdu_length = dlsch_pdu_rel15->transport_block_size/8; - TX_req->pdu_index = pdu_index++; - TX_req->num_segments = 1; - - return TBS/8; //Return TBS in bytes + params_rel15->rnti, + params_rel15->rnti_type, + params_rel15->config_type, + params_rel15->dci_format, + params_rel15->mux_pattern, + params_rel15->n_rb, + params_rel15->n_symb, + params_rel15->rb_offset, + params_rel15->first_symbol, + params_rel15->search_space_type); + nr_get_tbs_dl(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg); + TBS = dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15.transport_block_size; + LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS: %d\n", + dlsch_pdu_rel15->start_prb, + dlsch_pdu_rel15->n_prb, + dlsch_pdu_rel15->start_symbol, + dlsch_pdu_rel15->nb_symbols, + dlsch_pdu_rel15->nb_layers, + dlsch_pdu_rel15->nb_codewords, + dlsch_pdu_rel15->mcs_idx, + TBS); + dl_req->number_dci++; + dl_req->number_pdsch_rnti++; + dl_req->number_pdu+=2; + TX_req->pdu_length = dlsch_pdu_rel15->transport_block_size/8; + TX_req->pdu_index = pdu_index++; + TX_req->num_segments = 1; + return TBS/8; //Return TBS in bytes } @@ -293,223 +268,283 @@ int configure_fapi_dl_Tx(nfapi_nr_dl_config_request_body_t *dl_req, void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, frame_t frameP, - sub_frame_t slotP) -{ - LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest \n"); + sub_frame_t slotP, + nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config) { + LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest \n"); uint8_t CC_id; - gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; //NR_COMMON_channels_t *cc = nr_mac->common_channels; nfapi_nr_dl_config_request_body_t *dl_req; nfapi_tx_request_pdu_t *TX_req; uint16_t rnti = 0x1234; - nfapi_nr_config_request_t *cfg = &nr_mac->config[0]; - uint16_t sfn_sf = frameP << 7 | slotP; - // everything here is hard-coded to 30 kHz //int scs = get_dlscs(cfg); //int slots_per_frame = get_spf(cfg); - - int TBS; - int TBS_bytes; - int lcid; - int ta_len = 0; - int header_length_total=0; - int header_length_last; - int sdu_length_total = 0; - mac_rlc_status_resp_t rlc_status; - uint16_t sdu_lengths[NB_RB_MAX]; - int num_sdus = 0; - unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; - int offset; - int UE_id = 0; - unsigned char sdu_lcids[NB_RB_MAX]; - int padding = 0, post_padding = 0; - UE_list_t *UE_list = &nr_mac->UE_list; - - DLSCH_PDU DLSCH_pdu; - //DLSCH_PDU *DLSCH_pdu = (DLSCH_PDU*) malloc(sizeof(DLSCH_PDU)); - + int TBS; + int TBS_bytes; + int lcid; + int ta_len = 0; + int header_length_total=0; + int header_length_last; + int sdu_length_total = 0; + mac_rlc_status_resp_t rlc_status; + uint16_t sdu_lengths[NB_RB_MAX]; + int num_sdus = 0; + unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; + int offset; + int UE_id = 0; + unsigned char sdu_lcids[NB_RB_MAX]; + int padding = 0, post_padding = 0; + UE_list_t *UE_list = &nr_mac->UE_list; + DLSCH_PDU DLSCH_pdu; + //DLSCH_PDU *DLSCH_pdu = (DLSCH_PDU*) malloc(sizeof(DLSCH_PDU)); for (CC_id=0; CC_idDL_req[CC_id].dl_config_request_body; + TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus]; - LOG_D(MAC, "Scheduling UE specific search space DCI type 1 for CC_id %d\n",CC_id); - - dl_req = &nr_mac->DL_req[CC_id].dl_config_request_body; - TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus]; - - //The --NOS1 use case currently schedules DLSCH transmissions only when there is IP traffic arriving - //through the LTE stack - if (IS_SOFTMODEM_NOS1){ - - memset(&DLSCH_pdu, 0, sizeof(DLSCH_pdu)); + //The --NOS1 use case currently schedules DLSCH transmissions only when there is IP traffic arriving + //through the LTE stack + if (IS_SOFTMODEM_NOS1) { + memset(&DLSCH_pdu, 0, sizeof(DLSCH_pdu)); int ta_update = 31; ta_len = 0; - // Hardcode it for now TBS = 6784/8; //TBS in bytes - //nr_get_tbs(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg); + //nr_get_tbs_dl(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg); //TBS = dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15.transport_block_size; - for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - // TODO: check if the lcid is active + for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { + // TODO: check if the lcid is active + LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + module_idP, frameP, lcid, TBS, + TBS - ta_len - header_length_total - sdu_length_total - 3); - LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", - module_idP, frameP, lcid, TBS, - TBS - ta_len - header_length_total - sdu_length_total - 3); + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + slotP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS - ta_len - header_length_total - sdu_length_total - 3, + 0, + 0); - if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { - rlc_status = mac_rlc_status_ind(module_idP, - rnti, - module_idP, - frameP, - slotP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS - ta_len - header_length_total - sdu_length_total - 3 - //#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 - //#endif - ); + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC, + "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS: %d \n \n", + module_idP, frameP, + TBS - ta_len - header_length_total - sdu_length_total - 3, + lcid, + header_length_total, + TBS); + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS, + (char *)&dlsch_buffer[sdu_length_total], + 0, + 0); + LOG_D(MAC, + "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", + module_idP, sdu_lengths[num_sdus], lcid); + sdu_lcids[num_sdus] = lcid; + sdu_length_total += sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++; + UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; + UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; + header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); + header_length_total += header_length_last; + num_sdus++; + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + } + } else { + // no TBS left + break; + } + } - if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, - "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS: %d \n \n", - module_idP, frameP, - TBS - ta_len - header_length_total - sdu_length_total - 3, - lcid, - header_length_total, - TBS); + // last header does not have length field + if (header_length_total) { + header_length_total -= header_length_last; + header_length_total++; + } - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, - TBS, - (char *)&dlsch_buffer[sdu_length_total] - //#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 - //#endif - ); + if (ta_len + sdu_length_total + header_length_total > 0) { + if (TBS - header_length_total - sdu_length_total - ta_len <= 2) { + padding = TBS - header_length_total - sdu_length_total - ta_len; + post_padding = 0; + } else { + padding = 0; + post_padding = 1; + } - - - LOG_D(MAC, - "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", - module_idP, sdu_lengths[num_sdus], lcid); - - sdu_lcids[num_sdus] = lcid; - sdu_length_total += sdu_lengths[num_sdus]; - UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++; - UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; - UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; - UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; - - header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); - header_length_total += header_length_last; - - num_sdus++; - - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - } - } else { - // no TBS left - break; - } - } - - // last header does not have length field - if (header_length_total) { - header_length_total -= header_length_last; - header_length_total++; - } - - - if (ta_len + sdu_length_total + header_length_total > 0) { - - - if (TBS - header_length_total - sdu_length_total - ta_len <= 2) { - padding = TBS - header_length_total - sdu_length_total - ta_len; - post_padding = 0; - } else { - padding = 0; - post_padding = 1; - } - - offset = generate_dlsch_header((unsigned char *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0], //DLSCH_pdu.payload[0], - num_sdus, //num_sdus - sdu_lengths, // - sdu_lcids, 255, // no drx - ta_update, // timing advance - NULL, // contention res id - padding, post_padding); - LOG_D(MAC, "Offset bits: %d \n", offset); - - // Probably there should be other actions done before that - // cycle through SDUs and place in dlsch_buffer - - //memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total); + offset = generate_dlsch_header((unsigned char *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0], //DLSCH_pdu.payload[0], + num_sdus, //num_sdus + sdu_lengths, // + sdu_lcids, 255, // no drx + ta_update, // timing advance + NULL, // contention res id + padding, post_padding); + LOG_D(MAC, "Offset bits: %d \n", offset); + // Probably there should be other actions done before that + // cycle through SDUs and place in dlsch_buffer + //memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total); memcpy(&nr_mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total); - - // fill remainder of DLSCH with 0 - for (int j = 0; j < (TBS - sdu_length_total - offset); j++) { - //UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = 0; - nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0][offset + sdu_length_total + j] = 0; - } + // fill remainder of DLSCH with 0 + for (int j = 0; j < (TBS - sdu_length_total - offset); j++) { + //UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = 0; + nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0][offset + sdu_length_total + j] = 0; + } - TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &nr_mac->coreset[CC_id][1], &nr_mac->search_space[CC_id][1], nr_mac->pdu_index[CC_id]); + TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &nr_mac->coreset[CC_id][1], &nr_mac->search_space[CC_id][1], nr_mac->pdu_index[CC_id], dlsch_config); +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, , TBS size: %d \n \n", frameP, slotP, TBS_bytes); - #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, , TBS size: %d \n \n", frameP, slotP, TBS_bytes); - for(int i = 0; i < 10; i++) { // TBS_bytes dlsch_pdu_rel15->transport_block_size/8 6784/8 - LOG_I(MAC, "%x. ", ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); - } - #endif + for(int i = 0; i < 10; i++) { // TBS_bytes dlsch_pdu_rel15->transport_block_size/8 6784/8 + LOG_I(MAC, "%x. ", ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); + } - //TX_req->segments[0].segment_length = 8; - TX_req->segments[0].segment_length = TBS_bytes +2; - TX_req->segments[0].segment_data = nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0]; +#endif + //TX_req->segments[0].segment_length = 8; + TX_req->segments[0].segment_length = TBS_bytes +2; + TX_req->segments[0].segment_data = nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0]; + nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; + nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; + nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + } //if (ta_len + sdu_length_total + header_length_total > 0) + } //if (IS_SOFTMODEM_NOS1) + //When the --NOS1 option is not enabled, DLSCH transmissions with random data + //occur every time that the current function is called (dlsch phytest mode) + else { + TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &nr_mac->coreset[CC_id][1], &nr_mac->search_space[CC_id][1], nr_mac->pdu_index[CC_id], dlsch_config); + for(int i = 0; i < TBS_bytes; i++) { // + ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i] = (unsigned char) rand(); + //LOG_I(MAC, "%x. ", ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); + } - nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; - nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; - nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; - } //if (ta_len + sdu_length_total + header_length_total > 0) - } //if (IS_SOFTMODEM_NOS1) +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - //When the --NOS1 option is not enabled, DLSCH transmissions with random data - //occur every time that the current function is called (dlsch phytest mode) - else{ - TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &nr_mac->coreset[CC_id][1], &nr_mac->search_space[CC_id][1], nr_mac->pdu_index[CC_id]); - // HOT FIX for all zero pdu problem - // ------------------------------------------------------------------------------------------------ - - for(int i = 0; i < TBS_bytes; i++) { // - ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i] = (unsigned char) rand(); - //LOG_I(MAC, "%x. ", ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); - } - #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - if (frameP%100 == 0){ - LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes); - for(int i = 0; i < 10; i++) { - LOG_I(MAC, "%x. ", ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); - } - } - #endif - - //TX_req->segments[0].segment_length = 8; - TX_req->segments[0].segment_length = TBS_bytes +2; - TX_req->segments[0].segment_data = nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0]; + if (frameP%100 == 0) { + LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes); - nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; - nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; - nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; - // ------------------------------------------------------------------------------------------------ - } + for(int i = 0; i < 10; i++) { + LOG_I(MAC, "%x. ", ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); + } + } + +#endif + //TX_req->segments[0].segment_length = 8; + TX_req->segments[0].segment_length = TBS_bytes +2; + TX_req->segments[0].segment_data = nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0]; + nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; + nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; + nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + + } } //for (CC_id=0; CC_idUL_tti_req[CC_id]; + UL_tti_req->sfn = frameP; + UL_tti_req->slot = slotP; + UL_tti_req->n_pdus = 1; + UL_tti_req->pdus_list[0].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; + UL_tti_req->pdus_list[0].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); + nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; + memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t)); + /* + // original configuration + rel15_ul->rnti = 0x1234; + rel15_ul->ulsch_pdu_rel15.start_rb = 30; + rel15_ul->ulsch_pdu_rel15.number_rbs = 50; + rel15_ul->ulsch_pdu_rel15.start_symbol = 2; + rel15_ul->ulsch_pdu_rel15.number_symbols = 12; + rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; + rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; + rel15_ul->ulsch_pdu_rel15.Qm = 2; + rel15_ul->ulsch_pdu_rel15.mcs = 9; + rel15_ul->ulsch_pdu_rel15.rv = 0; + rel15_ul->ulsch_pdu_rel15.n_layers = 1; + */ + pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; + pusch_pdu->rnti = rnti; + pusch_pdu->handle = 0; //not yet used + //BWP related paramters - we don't yet use them as the PHY only uses one default BWP + //pusch_pdu->bwp_size; + //pusch_pdu->bwp_start; + //pusch_pdu->subcarrier_spacing; + //pusch_pdu->cyclic_prefix; + //pusch information always include + //this informantion seems to be redundant. with hthe mcs_index and the modulation table, the mod_order and target_code_rate can be determined. + pusch_pdu->mcs_index = 9; + pusch_pdu->mcs_table = 0; //0: notqam256 [TS38.214, table 5.1.3.1-1] - corresponds to nr_target_code_rate_table1 in PHY + pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; + pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; + pusch_pdu->transform_precoding = 0; + pusch_pdu->data_scrambling_id = 0; //It equals the higher-layer parameter Data-scrambling-Identity if configured and the RNTI equals the C-RNTI, otherwise L2 needs to set it to physical cell id.; + pusch_pdu->nrOfLayers = 1; + //DMRS + pusch_pdu->ul_dmrs_symb_pos = 1; + pusch_pdu->dmrs_config_type = 0; //dmrs-type 1 (the one with a single DMRS symbol in the beginning) + pusch_pdu->ul_dmrs_scrambling_id = 0; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id. + pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0. + //pusch_pdu->num_dmrs_cdm_grps_no_data; + //pusch_pdu->dmrs_ports; //DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used + //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] + pusch_pdu->resource_alloc = 1; //type 1 + //pusch_pdu->rb_bitmap;// for ressource alloc type 0 + pusch_pdu->rb_start = 0; + pusch_pdu->rb_size = 50; + pusch_pdu->vrb_to_prb_mapping = 0; + pusch_pdu->frequency_hopping = 0; + //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] + pusch_pdu->uplink_frequency_shift_7p5khz = 0; + //Resource Allocation in time domain + pusch_pdu->start_symbol_index = 2; + pusch_pdu->nr_of_symbols = 12; + //Optional Data only included if indicated in pduBitmap + pusch_pdu->pusch_data.rv_index = 0; + pusch_pdu->pusch_data.harq_process_id = 0; + pusch_pdu->pusch_data.new_data_indicator = 0; + pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->mcs_index, + pusch_pdu->target_code_rate, + pusch_pdu->rb_size, + pusch_pdu->nr_of_symbols, + 6, //nb_re_dmrs - not sure where this is coming from - its not in the FAPI + 0, //nb_rb_oh + pusch_pdu->nrOfLayers = 1); + pusch_pdu->pusch_data.num_cb = 0; //CBG not supported + //pusch_pdu->pusch_data.cb_present_and_position; + //pusch_pdu->pusch_uci; + //pusch_pdu->pusch_ptrs; + //pusch_pdu->dfts_ofdm; + //beamforming + //pusch_pdu->beamforming; //not used for now + } +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 4d96693831..d746756d65 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -399,8 +399,10 @@ void nr_configure_dci_from_pdcch_config(nfapi_nr_dl_config_pdcch_parameters_rel1 // first symbol //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored"); - for (int i=0; imonitoring_symbols_in_slot>>(31-i))&1) { + int sps = get_symbolsperslot(&cfg); + + for (int i=0; imonitoring_symbols_in_slot>>(sps-1-i))&1) { pdcch_params->first_symbol=i; break; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index c511ebe05f..d56d5d28c1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -34,6 +34,8 @@ #include "nr_mac_gNB.h" #include "PHY/defs_gNB.h" +void set_cset_offset(uint16_t); + void mac_top_init_gNB(void); void config_common(int Mod_idP, @@ -64,7 +66,9 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, frame_t frameP, sub_frame_t subframeP); -void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); +void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, + frame_t frame_txP, sub_frame_t slot_txP, + frame_t frame_rxP, sub_frame_t slot_rxP); void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); @@ -77,12 +81,18 @@ int configure_fapi_dl_Tx(nfapi_nr_dl_config_request_body_t *dl_req, nfapi_nr_config_request_t *cfg, nfapi_nr_coreset_t* coreset, nfapi_nr_search_space_t* search_space, - int16_t pdu_index); + int16_t pdu_index, + nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config); void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, frame_t frameP, - sub_frame_t slotP); + sub_frame_t slotP, + nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config); +void nr_schedule_uss_ulsch_phytest(nfapi_nr_ul_tti_request_t *UL_tti_req, + frame_t frameP, + sub_frame_t slotP); + void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params, nr_scs_e scs_common, nr_scs_e pdcch_scs, diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index e45c7f3b59..88f6c38758 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -44,6 +44,9 @@ extern RAN_CONTEXT_t RC; +void set_cset_offset(uint16_t offset_bits) { + RC.nrmac[0]->coreset[0][1].frequency_domain_resources >>= offset_bits; +} void nr_init_coreset(nfapi_nr_coreset_t *coreset) { @@ -66,7 +69,7 @@ void nr_init_search_space(nfapi_nr_search_space_t *search_space) search_space->duration = 5; search_space->slot_monitoring_periodicity = NFAPI_NR_SS_PERIODICITY_SL10; search_space->slot_monitoring_offset = 1; - search_space->monitoring_symbols_in_slot = 0xC0000000; // first 2 ofdm symbols + search_space->monitoring_symbols_in_slot = 0x3000; // 14 bits field search_space->css_formats_0_0_and_1_0 = 1; search_space->uss_dci_formats = 0; // enum to be defined-- formats 0.0 and 1.0 for (int i=0; iDL_req[j].dl_config_request_body.dl_config_pdu_list = RC.nrmac[i]->dl_config_pdu_list[j]; - RC.nrmac[i]->UL_req[j].ul_config_request_body.ul_config_pdu_list = RC.nrmac[i]->ul_config_pdu_list[j]; - for (int k = 0; k < 10; k++) - RC.nrmac[i]->UL_req_tmp[j][k].ul_config_request_body.ul_config_pdu_list =RC.nrmac[i]->ul_config_pdu_list_tmp[j][k]; + //FK changed UL_req to UL_tti_req, which does not contain a pointer to the pdu_list + //RC.nrmac[i]->UL_req[j].ul_config_request_body.ul_config_pdu_list = RC.nrmac[i]->ul_config_pdu_list[j]; + + //for (int k = 0; k < 10; k++) + // RC.nrmac[i]->UL_req_tmp[j][k].ul_config_request_body.ul_config_pdu_list =RC.nrmac[i]->ul_config_pdu_list_tmp[j][k]; + + RC.nrmac[i]->HI_DCI0_req[j].hi_dci0_request_body.hi_dci0_pdu_list = RC.nrmac[i]->hi_dci0_pdu_list[j]; + RC.nrmac[i]->TX_req[j].tx_request_body.tx_pdu_list = RC.nrmac[i]->tx_request_pdu[j]; + RC.nrmac[i]->ul_handle = 0; - RC.nrmac[i]->HI_DCI0_req[j].hi_dci0_request_body.hi_dci0_pdu_list = RC.nrmac[i]->hi_dci0_pdu_list[j]; - RC.nrmac[i]->TX_req[j].tx_request_body.tx_pdu_list = RC.nrmac[i]->tx_request_pdu[j]; - RC.nrmac[i]->ul_handle = 0; - - // Init PDCCH structures - nr_init_coreset(&RC.nrmac[i]->coreset[j][1]); - nr_init_search_space(&RC.nrmac[i]->search_space[j][1]); + // Init PDCCH structures + nr_init_coreset(&RC.nrmac[i]->coreset[j][1]); + nr_init_search_space(&RC.nrmac[i]->search_space[j][1]); } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index c8d5d3f385..7633279579 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -48,6 +48,7 @@ #include "NR_MeasConfig.h" #include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" #include "NR_PHY_INTERFACE/NR_IF_Module.h" #include "COMMON/platform_constants.h" @@ -118,16 +119,10 @@ typedef struct gNB_MAC_INST_s { nfapi_nr_config_request_t config[NFAPI_CC_MAX]; /// NFAPI DL Config Request Structure nfapi_nr_dl_config_request_t DL_req[NFAPI_CC_MAX]; - /// NFAPI UL Config Request Structure, send to L1 4 subframes before processing takes place - nfapi_ul_config_request_t UL_req[NFAPI_CC_MAX]; + /// NFAPI UL TTI Request Structure (this is from the new SCF specs) + nfapi_nr_ul_tti_request_t UL_tti_req[NFAPI_CC_MAX]; /// Preallocated DL pdu list nfapi_nr_dl_config_request_pdu_t dl_config_pdu_list[NFAPI_CC_MAX][MAX_NUM_DL_PDU]; - /// Preallocated UL pdu list - nfapi_ul_config_request_pdu_t ul_config_pdu_list[NFAPI_CC_MAX][MAX_NUM_UL_PDU]; - /// Preallocated UL pdu list for ULSCH (n+k delay) - nfapi_ul_config_request_pdu_t ul_config_pdu_list_tmp[NFAPI_CC_MAX][10][MAX_NUM_UL_PDU]; - /// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests - nfapi_ul_config_request_t UL_req_tmp[NFAPI_CC_MAX][10]; /// Preallocated HI_DCI0 pdu list nfapi_hi_dci0_request_pdu_t hi_dci0_pdu_list[NFAPI_CC_MAX][MAX_NUM_HI_DCI0_PDU]; /// NFAPI HI/DCI0 Config Request Structure diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index d9fe32098d..4c9804bdc0 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -271,8 +271,11 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { nfapi_nr_config_request_t *cfg = &mac->config[CC_id]; int spf = get_spf(cfg); gNB_dlsch_ulsch_scheduler(module_id, - (UL_info->frame+((UL_info->slot>(spf-1-sf_ahead))?1:0)) % 1024, - (UL_info->slot+sf_ahead)%spf); + UL_info->frame, + UL_info->slot, + (UL_info->frame+((UL_info->slot>(spf-1-sf_ahead))?1:0)) % 1024, + (UL_info->slot+sf_ahead)%spf); + ifi->CC_mask = 0; sched_info->module_id = module_id; sched_info->CC_id = CC_id; @@ -283,9 +286,9 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { if ((mac->common_channels[CC_id].tdd_Config==NULL) || (is_nr_UL_slot(&mac->common_channels[CC_id],(sched_info->slot+sf_ahead)%spf)>0)) - sched_info->UL_req = &mac->UL_req[CC_id]; + sched_info->UL_tti_req = &mac->UL_tti_req[CC_id]; else - sched_info->UL_req = NULL; + sched_info->UL_tti_req = NULL; sched_info->TX_req = &mac->TX_req[CC_id]; #ifdef DUMP_FAPI diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h index 67b00f6db4..898197cc30 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h @@ -35,6 +35,7 @@ #include #include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" #include "platform_constants.h" #include "platform_types.h" @@ -101,7 +102,7 @@ typedef struct { /// nFAPI DL Config Request nfapi_nr_dl_config_request_t *DL_req; /// nFAPI UL Config Request - nfapi_ul_config_request_t *UL_req; + nfapi_nr_ul_tti_request_t *UL_tti_req; /// nFAPI HI_DCI Request nfapi_hi_dci0_request_t *HI_DCI0_req; /// Pointers to DL SDUs diff --git a/openair2/NR_PHY_INTERFACE/nfapi_5g_test.c b/openair2/NR_PHY_INTERFACE/nfapi_5g_test.c new file mode 100644 index 0000000000..7736252a07 --- /dev/null +++ b/openair2/NR_PHY_INTERFACE/nfapi_5g_test.c @@ -0,0 +1,20 @@ + + +//openair2/NR_PHY_INTERFACE/nfapi_5g_test.c +#include "nfapi_nr_interface_scf.h" + +#include // for printf + +int main ( int argc, char** argv) +{ + nfapi_nr_cell_param_t nfapi_nr_cell_param_test; + nfapi_nr_param_tlv_t* tlvs_to_report_list; + nfapi_nr_cell_param_test.config_tlvs_to_report_list = tlvs_to_report_list; + nfapi_nr_cell_param_test.phy_state = 0; + nfapi_nr_cell_param_test.release_capability = 0; + nfapi_nr_cell_param_test.skip_blank_dl_config = 0; + nfapi_nr_cell_param_test.skip_blank_ul_config = 0; + + printf(" test nfapi \n"); + return 0; +} diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index 192578dea6..16b86cfd64 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -126,7 +126,7 @@ int load_lib(openair0_device *device, libname=OAI_RFSIM_LIBNAME; shlib_fdesc[0].fname="device_init"; } else if (flag == RAU_LOCAL_RADIO_HEAD) { - if (getenv("RFSIMULATOR") != NULL) + if (IS_SOFTMODEM_RFSIM) libname="rfsimulator"; else libname=OAI_RF_LIBNAME; diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 86d64a16b0..76d0ad6674 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -70,8 +70,8 @@ typedef struct complex16 sample_t; // 2*16 bits complex number typedef struct buffer_s { int conn_sock; openair0_timestamp lastReceivedTS; - openair0_timestamp lastWroteTS; bool headerMode; + bool trashingPacket; samplesBlockHeader_t th; char *transferPtr; uint64_t remainToTransfer; @@ -83,6 +83,7 @@ typedef struct buffer_s { typedef struct { int listen_sock, epollfd; openair0_timestamp nextTimestamp; + openair0_timestamp lastWroteTS; uint64_t typeStamp; char *ip; uint16_t port; @@ -102,11 +103,11 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) { ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1); ptr->conn_sock=sock; ptr->lastReceivedTS=0; - ptr->lastWroteTS=0; ptr->headerMode=true; + ptr->trashingPacket=false; ptr->transferPtr=(char *)&ptr->th; ptr->remainToTransfer=sizeof(samplesBlockHeader_t); - int sendbuff=1000*1000*10; + int sendbuff=1000*1000*100; AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, ""); struct epoll_event ev= {0}; ev.events = EPOLLIN | EPOLLRDHUP; @@ -183,7 +184,7 @@ void setblocking(int sock, enum blocking_t active) { AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, ""); } -static bool flushInput(rfsimulator_state_t *t, int timeout); +static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps); void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { if (t->saveIQfile != -1) { @@ -207,7 +208,8 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { if(errno==EAGAIN) { // The opposite side is saturated // we read incoming sockets meawhile waiting - flushInput(t, 5); + //flushInput(t, 5); + usleep(500); continue; } else return; @@ -218,8 +220,6 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { } } - - void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { char *saveF=NULL; char *modelname=NULL; @@ -316,19 +316,18 @@ sin_addr: return 0; } -int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) { - rfsimulator_state_t *t = device->priv; +static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags, bool alreadyLocked) { + if (!alreadyLocked) + pthread_mutex_lock(&Sockmutex); + LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp); for (int i=0; ibuf[i]; if (b->conn_sock >= 0 ) { - if ( abs((double)b->lastWroteTS-timestamp) > (double)CirSize ) - LOG_E(HW,"Tx/Rx shift too large Tx:%lu, Rx:%lu\n", b->lastWroteTS, b->lastReceivedTS); - samplesBlockHeader_t header= {t->typeStamp, nsamps, nbAnt, timestamp}; - fullwrite(b->conn_sock, &header, sizeof(header), t); + fullwrite(b->conn_sock,&header, sizeof(header), t); sample_t tmpSamples[nsamps][nbAnt]; for(int a=0; aconn_sock >= 0 ) { fullwrite(b->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t); - b->lastWroteTS=timestamp+nsamps; } } } + if ( t->lastWroteTS != 0 && abs((double)t->lastWroteTS-timestamp) > (double)CirSize) + LOG_E(HW,"Discontinuous TX gap too large Tx:%lu, %lu\n", t->lastWroteTS, timestamp); + + AssertFatal(t->lastWroteTS <= timestamp+1, " Not supported to send Tx out of order (same in USRP) %lu, %lu\n", + t->lastWroteTS, timestamp); + t->lastWroteTS=timestamp+nsamps; + + if (!alreadyLocked) + pthread_mutex_unlock(&Sockmutex); + LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n", nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) ); - // Let's verify we don't have incoming data - // This is mandatory when the opposite side doesn't transmit - flushInput(t, 0); - pthread_mutex_unlock(&Sockmutex); return nsamps; } -static bool flushInput(rfsimulator_state_t *t, int timeout) { +int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) { + return rfsimulator_write_internal(device->priv, timestamp, samplesVoid, nsamps, nbAnt, flags, false); +} + +static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initial) { // Process all incoming events on sockets // store the data in lists struct epoll_event events[FD_SETSIZE]= {0}; @@ -375,7 +383,16 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) { AssertFatal( (conn_sock = accept(t->listen_sock,NULL,NULL)) != -1, ""); setblocking(conn_sock, notBlocking); allocCirBuf(t, conn_sock); - LOG_I(HW,"A ue connected\n"); + LOG_I(HW,"A ue connected, sending the current time\n"); + struct complex16 v= {0}; + void *samplesVoid[t->tx_num_channels]; + + for ( int i=0; i < t->tx_num_channels; i++) + samplesVoid[i]=(void *)&v; + + rfsimulator_write_internal(t, t->lastWroteTS > 1 ? t->lastWroteTS-1 : 0, + samplesVoid, 1, + t->tx_num_channels, 1, false); } else { if ( events[nbEv].events & (EPOLLHUP | EPOLLERR | EPOLLRDHUP) ) { socketError(t,fd); @@ -421,40 +438,60 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) { (t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol"); b->headerMode=false; - if ( b->lastReceivedTS != b->th.timestamp) { + if ( t->nextTimestamp == 0 ) { // First block in UE, resync with the eNB current TS + t->nextTimestamp=b->th.timestamp> nsamps_for_initial ? + b->th.timestamp - nsamps_for_initial : + 0; + b->lastReceivedTS=b->th.timestamp> nsamps_for_initial ? + b->th.timestamp : + nsamps_for_initial; + LOG_W(HW,"UE got first timestamp: starting at %lu\n", t->nextTimestamp); + b->trashingPacket=true; + } else if ( b->lastReceivedTS < b->th.timestamp) { int nbAnt= b->th.nbAnt; - + for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) { for (int a=0; a < nbAnt; a++) { b->circularBuf[(index*nbAnt+a)%CirSize].r=0; b->circularBuf[(index*nbAnt+a)%CirSize].i=0; } } + if (b->lastReceivedTS != 0 && b->th.timestamp-b->lastReceivedTS > 50 ) + LOG_W(HW,"UEsock: %d gap of: %ld in reception\n", fd, b->th.timestamp-b->lastReceivedTS ); + b->lastReceivedTS=b->th.timestamp; + + } else if ( b->lastReceivedTS > b->th.timestamp && b->th.size == 1 ) { + LOG_W(HW,"Received Rx/Tx synchro out of order\n"); + b->trashingPacket=true; + } else if ( b->lastReceivedTS == b->th.timestamp ) { + // normal case + } else { + abort(); + AssertFatal(false, "received data in past: current is %lu, new reception: %lu!\n", b->lastReceivedTS, b->th.timestamp); } - LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS ); - } + pthread_mutex_lock(&Sockmutex); - b->lastReceivedTS=b->th.timestamp; - AssertFatal(b->lastWroteTS == 0 || ( abs((double)b->lastWroteTS-b->lastReceivedTS) < (double)CirSize), - "Tx/Rx shift too large Tx:%lu, Rx:%lu\n", b->lastWroteTS, b->lastReceivedTS); + if (t->lastWroteTS != 0 && ( abs((double)t->lastWroteTS-b->lastReceivedTS) > (double)CirSize)) + LOG_E(HW,"UEsock: %d Tx/Rx shift too large Tx:%lu, Rx:%lu\n", fd, t->lastWroteTS, b->lastReceivedTS); + + pthread_mutex_unlock(&Sockmutex); b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize]; b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt); } if ( b->headerMode==false ) { - LOG_D(HW,"Set b->lastReceivedTS %ld\n", b->lastReceivedTS); - b->lastReceivedTS=b->th.timestamp+b->th.size-byteToSample(b->remainToTransfer,b->th.nbAnt); + LOG_D(HW,"UEsock: %d Set b->lastReceivedTS %ld\n", fd, b->lastReceivedTS); + if ( ! b->trashingPacket ) { + b->lastReceivedTS=b->th.timestamp+b->th.size-byteToSample(b->remainToTransfer,b->th.nbAnt); + } - // First block in UE, resync with the eNB current TS - if ( t->nextTimestamp == 0 ) - t->nextTimestamp=b->lastReceivedTS-b->th.size; - - if ( b->remainToTransfer==0) { - LOG_D(HW,"Completed block reception: %ld\n", b->lastReceivedTS); - b->headerMode=true; - b->transferPtr=(char *)&b->th; - b->remainToTransfer=sizeof(samplesBlockHeader_t); - b->th.magic=-1; + if ( b->remainToTransfer==0) { + LOG_D(HW,"UEsock: %d Completed block reception: %ld\n", fd, b->lastReceivedTS); + b->headerMode=true; + b->transferPtr=(char *)&b->th; + b->remainToTransfer=sizeof(samplesBlockHeader_t); + b->th.magic=-1; + b->trashingPacket=false; } } } @@ -468,7 +505,6 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo LOG_W(HW, "rfsimulator: only 1 antenna tested\n"); } - pthread_mutex_lock(&Sockmutex); rfsimulator_state_t *t = device->priv; LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps); // deliver data from received data @@ -484,45 +520,58 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo if ( t->nextTimestamp == 0) LOG_W(HW,"No connected device, generating void samples...\n"); - if (!flushInput(t, 10)) { + if (!flushInput(t, 10, nsamps)) { for (int x=0; x < nbAnt; x++) memset(samplesVoid[x],0,sampleToByte(nsamps,1)); t->nextTimestamp+=nsamps; - LOG_D(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp); + + if ( ((t->nextTimestamp/nsamps)%100) == 0) + LOG_W(HW,"No UE, Generated void samples for Rx: %ld\n", t->nextTimestamp); + *ptimestamp = t->nextTimestamp-nsamps; - pthread_mutex_unlock(&Sockmutex); return nsamps; } } else { + pthread_mutex_lock(&Sockmutex); + + if ( t->nextTimestamp > 0 && t->lastWroteTS < t->nextTimestamp) { + pthread_mutex_unlock(&Sockmutex); + usleep(10000); + pthread_mutex_lock(&Sockmutex); + if ( t->lastWroteTS < t->nextTimestamp ) { + // Assuming Tx is not done fully in another thread + // We can never write is the past from the received time + // So, the node perform receive but will never write these symbols + // let's tell this to the opposite node + // We send timestamp for nb samples required + // assuming this should have been done earlier if a Tx would exist + pthread_mutex_unlock(&Sockmutex); + struct complex16 v= {0}; + void *samplesVoid[t->tx_num_channels]; + + for ( int i=0; i < t->tx_num_channels; i++) + samplesVoid[i]=(void *)&v; + LOG_I(HW, "No samples Tx occured, so we send 1 sample to notify it: Tx:%lu, Rx:%lu\n", + t->lastWroteTS, t->nextTimestamp); + rfsimulator_write_internal(t, t->nextTimestamp, + samplesVoid, 1, + t->tx_num_channels, 1, true); + } else { + pthread_mutex_unlock(&Sockmutex); + LOG_W(HW, "trx_write came from another thread\n"); + } + } else + pthread_mutex_unlock(&Sockmutex); + bool have_to_wait; do { have_to_wait=false; - for (int sock=0; sockbuf[sock]; - if ( b->circularBuf) { - LOG_D(HW,"sock: %d, lastWroteTS: %lu, lastRecvTS: %lu, TS must be avail: %lu\n", - sock, b->lastWroteTS, - b->lastReceivedTS, - t->nextTimestamp+nsamps); - - if ( b->lastReceivedTS > b->lastWroteTS ) { - // The caller modem (NB, UE, ...) must send Tx in advance, so we fill TX if Rx is in advance - // This occurs for example when UE is in sync mode: it doesn't transmit - // with USRP, it seems ok: if "tx stream" is off, we may consider it actually cuts the Tx power - struct complex16 v = {0}; - void *samplesVoid[b->th.nbAnt]; - - for ( int i=0; i < b->th.nbAnt; i++) - samplesVoid[i]=(void *)&v; - - rfsimulator_write(device, b->lastReceivedTS, samplesVoid, 1, b->th.nbAnt, 0); - } - } - if ( b->circularBuf ) if ( t->nextTimestamp+nsamps > b->lastReceivedTS ) { have_to_wait=true; @@ -535,7 +584,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo ptr->lastReceivedTS, t->nextTimestamp+nsamps); */ - flushInput(t, 3); + flushInput(t, 3, nsamps); } while (have_to_wait); } @@ -582,7 +631,6 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo nsamps, *ptimestamp, t->nextTimestamp, signal_energy(samplesVoid[0], nsamps)); - pthread_mutex_unlock(&Sockmutex); return nsamps; } int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) { @@ -613,7 +661,6 @@ __attribute__((__visibility__("default"))) int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { // to change the log level, use this on command line // --log_config.hw_log_level debug - // (for phy layer, replace "hw" by "phy") rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1); rfsimulator_readconfig(rfsimulator); pthread_mutex_init(&Sockmutex, NULL); @@ -629,7 +676,6 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { device->trx_set_gains_func = rfsimulator_set_gains; device->trx_write_func = rfsimulator_write; device->trx_read_func = rfsimulator_read; - device->uhd_set_thread_priority = NULL; /* let's pretend to be a b2x0 */ device->type = USRP_B200_DEV; device->openair0_cfg=&openair0_cfg[0]; diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index fcb3c94b90..42752b44e0 100644 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -14,11 +14,11 @@ // now , if we use --mu option in UE, compiling error will occur. // This problem will be fixed in the future. # ifndef UESIM_EXPANSION -# define NUMBER_OF_UE_MAX 16 -# define NUMBER_OF_NR_UE_MAX 16 -# define NUMBER_OF_UCI_VARS_MAX 56 -# define NUMBER_OF_CONNECTED_eNB_MAX 3 -# define NUMBER_OF_CONNECTED_gNB_MAX 3 +# define NUMBER_OF_UE_MAX 4 +# define NUMBER_OF_NR_UE_MAX 4 +# define NUMBER_OF_UCI_VARS_MAX 14 +# define NUMBER_OF_CONNECTED_eNB_MAX 1 +# define NUMBER_OF_CONNECTED_gNB_MAX 1 # else # define NUMBER_OF_UE_MAX 256 # define NUMBER_OF_NR_UE_MAX 16 diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index a1762187a5..044c044fd6 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -255,7 +255,7 @@ RUs = ( max_rxgain = 114; eNB_instances = [0]; - sdr_addrs = "addr=192.168.50.2,second_addr=192.168.30.2,clock_source=external,time_source=external"; + sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2,clock_source=external,time_source=external"; } ); @@ -285,9 +285,9 @@ NETWORK_CONTROLLER : global_log_verbosity ="medium"; hw_log_level ="info"; hw_log_verbosity ="medium"; - phy_log_level ="info"; + phy_log_level ="debug"; phy_log_verbosity ="medium"; - mac_log_level ="info"; + mac_log_level ="debug"; mac_log_verbosity ="high"; rlc_log_level ="info"; rlc_log_verbosity ="medium";