Commit 56ecc5cf authored by Wang Tsu-Han's avatar Wang Tsu-Han

Merge branch 'develop-nr' into ru-parallel-beamforming-merge

Conflicts:
	openair1/PHY/MODULATION/nr_modulation.h
	openair1/PHY/NR_TRANSPORT/nr_dlsch.c
	openair1/SCHED_NR/phy_procedures_nr_gNB.c
parents e0c80a83 90445b00
{
// 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
......@@ -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 ."
}
}
......
......@@ -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
......
......@@ -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
......
......@@ -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)
......
......@@ -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"
}
......
......@@ -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
......
......@@ -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
......
......@@ -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)
......
......@@ -1081,18 +1081,35 @@
<class>execution</class>
<desc>nr_dlsim Test cases. (Test1: 106 PRB),
(Test2: 217 PRB),
(Test3: 273 PRB)</desc>
(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</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
<pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec>
<pre_exec_args></pre_exec_args>
<main_exec> $OPENAIR_DIR/targets/bin/nr_dlsim.Rel15</main_exec>
<main_exec_args>-n100 -R106
-n100 -R217
-n100 -R273</main_exec_args>
<tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3</tags>
<search_expr_true>PDCCH test OK</search_expr_true>
<main_exec_args>-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</main_exec_args>
<tags>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</tags>
<search_expr_true>PDSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
</testCase>
......@@ -1220,6 +1237,30 @@
<nruns>3</nruns>
</testCase>
<testCase id="015111">
<class>execution</class>
<desc>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)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
<pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec>
<pre_exec_args></pre_exec_args>
<main_exec> $OPENAIR_DIR/targets/bin/nr_ulsim.Rel15</main_exec>
<main_exec_args>-f100 -m9 -r106 -s10
-f100 -m16 -s20
-f100 -m28 -s30
-f100 -m9 -R217 -r217 -s10
-f100 -m9 -R273 -r273 -s10</main_exec_args>
<tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5</tags>
<search_expr_true>PUSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
</testCase>
<testCase id="015500" >
<class>lte-softmodem</class>
<desc></desc>
......
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
......@@ -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;
......
......@@ -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);
......
......@@ -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
The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client.
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.
# 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_<core id>"
The threads are all Linux real time scheduler, their name is set automatically is "Tpool_<core id>"
## 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;
* 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
* 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
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.
......@@ -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;i<gNB->num_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;
}
}
......
......@@ -81,6 +81,7 @@
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "enb_config.h"
#include <executables/nr-softmodem.h>
#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) {
......
......@@ -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);
......
......@@ -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; i<UE->frame_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; i<UE->frame_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
......
......@@ -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;
......
This diff is collapsed.
......@@ -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<n_segments;j++) {
ldpc_encoder_orig(test_input[j], channel_input[j],block_length,BG,0);
ldpc_encoder_orig(test_input[j], channel_input[j],Zc,Kb,block_length,BG,0);
}
stop_meas(&time);
/* start_meas(time_optim);
ldpc_encoder_optim_8seg(test_input,channel_input_optim,block_length,BG,n_segments,&tinput,&tprep,&tparity,&toutput);
ldpc_encoder_optim_8seg(test_input,channel_input_optim,Zc,Kb,block_length,BG,n_segments,&tinput,&tprep,&tparity,&toutput);
for(j=0;j<n_segments;j++) {
ldpc_encoder_optim(test_input[j],channel_input_optim[j],block_length,BG,&tinput,&tprep,&tparity,&toutput);
ldpc_encoder_optim(test_input[j],channel_input_optim[j],Zc,Kb,block_length,BG,&tinput,&tprep,&tparity,&toutput);
}
stop_meas(time_optim);*/
for(j=0;j<(n_segments%8+1);j++) {
for(j=0;j<(n_segments/8+1);j++) {
start_meas(time_optim);
ldpc_encoder_optim_8seg_multi(test_input,channel_input_optim,block_length, BG, n_segments,j,&tinput,&tprep,&tparity,&toutput);
ldpc_encoder_optim_8seg_multi(test_input,channel_input_optim,Zc,Kb,block_length, BG, n_segments,j,&tinput,&tprep,&tparity,&toutput);
stop_meas(time_optim);
}
......
......@@ -241,8 +241,8 @@ if (logFlag){
start_meas(&timeEncoder);
if (decoder_int16==1) {
polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, currentPtr);
//polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0, currentPtr);
polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, 0, currentPtr);
//polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0,0,currentPtr);
} else { //0 --> 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,
......
......@@ -454,14 +454,21 @@ int32_t nr_segmentation(unsigned char *input_buffer,
unsigned int *C,
unsigned int *K,
unsigned int *Zout,
unsigned int *F);
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);
unsigned int *F,
uint8_t BG);
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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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
......
......@@ -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
......
......@@ -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,
......
......@@ -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; n<quadwlen; n++) if (n==0) B[n] = (A[n] << polarParams->crcParityBits) | tcrc;
else B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits));
......
......@@ -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)<<n);
for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
if ((double)Tbstable_nr[i] >= 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<<n)))<<n);
if (R <= 256) { //1/4
C = ceil( (Np_info + 24)/3816 );
nr_tbs = (uint32_t)(8 * C * ceil( (Np_info + 24)/(8*C) ) - 24);
if (R <= 256) {
C = CEILIDIV((Np_info+24),3816);
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
}
else {
if (Np_info > 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;
}
//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)<<n);
for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
if (Tbstable_nr[i] >= Np_info){
nr_tbs = Tbstable_nr[i];
break;
}
}
}
else {
n = log2(Ninfo-24)-5;
Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
if (R <= 256) {
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
}
else {
if (Np_info > 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;
return nr_tbs;
}
......@@ -206,3 +206,4 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
return 0;
}
......@@ -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);
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;
}
......
......@@ -484,29 +484,20 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
}
}
for (i=0; i<NUMBER_OF_NR_UE_MAX; i++) {
for (i=0; i<NUMBER_OF_NR_ULSCH_MAX; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
for (j=0; j<2; j++) {
// ULSCH for RA
if(i==0) {
gNB->ulsch[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);
......
......@@ -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 );
}
}
......
......@@ -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)
{
......
......@@ -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,
......
......@@ -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; idxP<ceil((float)nb_rb_pusch*12/8); idxP++) {
for(uint8_t idxI=0; idxI<16; idxI+=2) {
printf("%d\t%d\t",ul_ch[idxP*16+idxI],ul_ch[idxP*16+idxI+1]);
}
printf("%d\n",idxP);
}
#endif
// Convert to time domain
memset(temp_in_ifft_0, 0, gNB->frame_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
}
......@@ -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
......
......@@ -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<NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD; n++) {
x1 = (x1>>1) ^ (x1>>4);
x1 = x1 ^ (x1<<31) ^ (x1<<28);
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
......
......@@ -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<cset_start_symb + pdcch_params.n_symb; symb++)
gold_pdcch_dmrs[symb] += (pdcch_params.rb_offset*3)>>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<cset_start_symb + pdcch_params.n_symb; symb++) {
if (dmrs_offset) {
// a non zero offset requires the DMRS sequence to be rearranged
memset(dmrs_seq,0, NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
for (int i=0; i<dmrs_length; i++) {
dmrs_seq[(i>>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<dmrs_length>>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_idx<dci_alloc.L; cce_idx++) {
cce = dci_alloc.cce_list[cce_idx];
for (int reg_idx=0; reg_idx<NR_NB_REG_PER_CCE; reg_idx++) {
reg = cce.reg_list[reg_idx];
reg_mapping_list[reg.symb_idx*regs_per_symb + symb_idx[reg.symb_idx]++] = reg;
reg_mapping_list[reg_idx+cce_idx*NR_NB_REG_PER_CCE] = reg;
}
}
#ifdef DEBUG_DCI
printf("\n Ordered REG list:\n");
for (int i=0; i<nb_regs; i++)
printf("%d\t",reg_mapping_list[i].reg_idx );
printf("\n");
#endif
if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS) {
/*in this case the DMRS are mapped on all the coreset*/
for (l=cset_start_symb; l<cset_start_symb+ cset_nsymb; l++) {
dmrs_idx = 0;
// dmrs index depends on reference point for k according to 38.211 7.4.1.3.2
if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
dmrs_idx = 0;
else
dmrs_idx = pdcch_params.rb_offset*3;
k = cset_start_sc + 1;
while (dmrs_idx<3*pdcch_params.n_rb) {
......@@ -333,7 +300,13 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
k -= frame_parms.ofdm_symbol_size;
l = cset_start_symb + reg.symb_idx;
dmrs_idx = (reg.reg_idx/cset_nsymb)*3;
// dmrs index depends on reference point for k according to 38.211 7.4.1.3.2
if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
dmrs_idx = (reg.reg_idx/cset_nsymb)*3;
else
dmrs_idx = ((reg.reg_idx/cset_nsymb)+pdcch_params.rb_offset)*3;
k_prime = 0;
for (int m=0; m<NR_NB_SC_PER_RB; m++) {
......
......@@ -30,7 +30,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
uint16_t N_RB,
nfapi_nr_config_request_t *config);
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,
......@@ -38,7 +38,7 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
nfapi_nr_config_request_t config);
void nr_pdcch_scrambling(uint32_t *in,
uint16_t size,
uint32_t size,
uint32_t Nid,
uint32_t n_RNTI,
uint32_t *out);
......
......@@ -39,11 +39,11 @@
//#define DEBUG_DLSCH_MAPPING
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) {
uint8_t reset, b_idx;
uint32_t x1, x2, s=0;
......@@ -88,7 +88,7 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
int8_t Wf[2], Wt[2], l0, l_prime[2], delta;
uint16_t nb_symbols = rel15->nb_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; q<rel15->nb_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; l<rel15->nb_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; l<rel15->start_symbol+rel15->nb_symbols; l++) {
k = start_sc;
......
......@@ -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,
......
......@@ -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;
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);
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);
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)+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);
F = dlsch->harq_processes[harq_pid]->F;
Coderate = (float) A /(float) G;
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){
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
BG = 2;
}
else{
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;
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; r<dlsch->harq_processes[harq_pid]->C; r++) {
//d_tmp[r] = &dlsch->harq_processes[harq_pid]->d[r][0];
......@@ -374,31 +394,20 @@ 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]);
/*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);
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("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);
......@@ -409,13 +418,14 @@ int nr_dlsch_encoding(unsigned char *a,
for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
if (dlsch->harq_processes[harq_pid]->F>0) {
for (int k=(Kr-F-2*(*pz)); k<Kr-2*(*pz); k++) {
dlsch->harq_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)); k<Kr-2*(*Zc); k++) {
dlsch->harq_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
......
......@@ -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; i<NUMBER_OF_NR_DLSCH_MAX; i++) {
AssertFatal(gNB->dlsch[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; i<NUMBER_OF_NR_ULSCH_MAX; i++) {
AssertFatal(gNB->ulsch[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_id<NUMBER_OF_NR_ULSCH_MAX),
"illegal or no ulsch_id found!!! rnti %04x ulsch_id %d\n",ulsch_pdu->rnti,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_pid;
ulsch->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;
}
......@@ -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
......
......@@ -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;
}
......
......@@ -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);
......@@ -31,32 +31,61 @@
*/
#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};
uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx) {
//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}};
//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);
return (Table_51313[Imcs][0]);
break;
case 3:
return (((Imcs<15)||(Imcs==29))?2:((Imcs<21)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1);
default:
AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", 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 (Table_51312[Imcs][1]);
break;
case 2:
return (Table_51313[Imcs][1]);
break;
default:
......@@ -64,22 +93,57 @@ 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) {
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 (nr_target_code_rate_table1[Imcs]);
return (Table_51312[Imcs][1]);
break;
case 2:
return (nr_target_code_rate_table2[Imcs]);
return (Table_51313[Imcs][1]);
break;
case 3:
return (nr_target_code_rate_table3[Imcs]);
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,3])\n", table_idx);
AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx);
}
}
......@@ -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;
if (Ninfo <= 3824) {
n = max(3, (log2(Ninfo)-6));
Ninfo_prime = max(24, (Ninfo>>n)<<n);
for (int i=0; i<93; i++)
if (nr_tbs_table[i] >= Ninfo_prime) {
TBS = nr_tbs_table[i];
break;
}
}
else {
n = log2(Ninfo-24)-5;
Ninfo_prime = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
if (R<256) {
C = CEILIDIV((Ninfo_prime+24),3816);
TBS = (C<<3)*CEILIDIV((Ninfo_prime+24),(C<<3)) - 24;
}
else {
if (Ninfo_prime>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;
}
}
table_idx = 0;
R = nr_get_code_rate_dl(Imcs, table_idx);
Qm = nr_get_Qm_dl(Imcs, table_idx);
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) {
......
......@@ -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);
......
......@@ -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);
......@@ -48,6 +48,7 @@
#include "common/utils/LOG/log.h"
#include <syscall.h>
//#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);
#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
}
if (R<1024)
Coderate = (float) R /(float) 1024;
else
Coderate = (float) 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;
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; r<harq_process->C; 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;
......
......@@ -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);
......
......@@ -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};
......@@ -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
......@@ -60,8 +60,8 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
temp = 0;
for (aa=0; aa<frame_parms->nb_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);
......
......@@ -726,7 +726,7 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
ch_offset = ue->frame_parms.ofdm_symbol_size*2;
printf("testing measurements\n");
//printf("testing measurements\n");
// signal measurements
for (eNB_id=0; eNB_id<ue->n_connected_eNB; eNB_id++) {
......
......@@ -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);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment