diff --git a/ci-scripts/ran_dashboard/Hdashboard.py b/ci-scripts/ran_dashboard/Hdashboard.py index 993d0dded8..bfa07557bd 100644 --- a/ci-scripts/ran_dashboard/Hdashboard.py +++ b/ci-scripts/ran_dashboard/Hdashboard.py @@ -529,14 +529,14 @@ class Dashboard: mr_notes = editable_mr.notes.list(all=True) body = '[Consolidated Test Results](https://oaitestdashboard.s3.eu-west-1.amazonaws.com/MR'+mr+'/index.html)\\\n' - body += 'Tested CommitID: ' + commit + '\\\n' + body += 'Tested CommitID: ' + commit for i in range(0,n_tests): jobname = args[4*i] buildurl = args[4*i+1] buildid = args[4*i+2] status = args[4*i+3] - body += jobname+': **'+status+'** ([' + buildid + '](' + buildurl + '))\\\n' + body += '\\\n' + jobname + ': **'+status+'** ([' + buildid + '](' + buildurl + '))' #create new note mr_note = editable_mr.notes.create({ diff --git a/ci-scripts/xml_files/fr1_gnb_build.xml b/ci-scripts/xml_files/fr1_gnb_build.xml index 13d85fccc4..1ddc5b5682 100644 --- a/ci-scripts/xml_files/fr1_gnb_build.xml +++ b/ci-scripts/xml_files/fr1_gnb_build.xml @@ -32,7 +32,7 @@ Build_eNB Build gNB - -w USRP -c --gNB --ninja + -w USRP -c --gNB --ninja --noavx512 0 0 True diff --git a/ci-scripts/xml_files/fr1_multi_node_build.xml b/ci-scripts/xml_files/fr1_multi_node_build.xml index 60bc734e65..2dbdfb2f9d 100644 --- a/ci-scripts/xml_files/fr1_multi_node_build.xml +++ b/ci-scripts/xml_files/fr1_multi_node_build.xml @@ -50,7 +50,7 @@ Build_eNB Build gNB - -w USRP -c --gNB --ninja + -w USRP -c --gNB --ninja --noavx512 1 1 True diff --git a/ci-scripts/xml_files/gnb_usrp_build.xml b/ci-scripts/xml_files/gnb_usrp_build.xml index 97f85c6a33..81c7d4e24e 100644 --- a/ci-scripts/xml_files/gnb_usrp_build.xml +++ b/ci-scripts/xml_files/gnb_usrp_build.xml @@ -34,7 +34,7 @@ TesteNB Build_eNB Build gNB (USRP) - --gNB -w USRP --ninja --cmake-opt -DBoost_INCLUDE_DIR=/usr/include/boost169 + --gNB -w USRP --ninja --cmake-opt -DBoost_INCLUDE_DIR=/usr/include/boost169 --noavx512 True diff --git a/ci-scripts/xml_files/ldpc_gpu_test.xml b/ci-scripts/xml_files/ldpc_gpu_test.xml index a0191fbd76..c17bc082d5 100644 --- a/ci-scripts/xml_files/ldpc_gpu_test.xml +++ b/ci-scripts/xml_files/ldpc_gpu_test.xml @@ -32,7 +32,7 @@ Build_PhySim Build for physical simulator - --phy_simulators --ninja + --phy_simulators --ninja --noavx512 FALSE diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index ef7d6c4322..c763c8950d 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -206,17 +206,23 @@ if (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l") else (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l") if(EXISTS "/proc/cpuinfo") file(STRINGS "/proc/cpuinfo" CPUINFO REGEX flags LIMIT_COUNT 1) - if (CPUINFO MATCHES "avx2") - set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mavx2") + message("NOAVX512 is ${NOAVX512}") + if (CPUINFO MATCHES "avx512bw" AND "${NOAVX512}" STREQUAL "False") + set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mavx512bw -march=skylake-avx512 -mtune=skylake-avx512 " ) set(COMPILATION_AVX2 "True") else() - set(COMPILATION_AVX2 "False") - endif() - if (CPUINFO MATCHES "sse4_1") - set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -msse4.1 -mpclmul") - endif() - if (CPUINFO MATCHES "ssse3") - set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mssse3") + if (CPUINFO MATCHES "avx2") + set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mavx2") + set(COMPILATION_AVX2 "True") + else() + set(COMPILATION_AVX2 "False") + endif() + if (CPUINFO MATCHES "sse4_1") + set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -msse4.1 -mpclmul") + endif() + if (CPUINFO MATCHES "ssse3") + set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mssse3") + endif() endif() else() Message("/proc/cpuinfo does not exit. We will use manual CPU flags") @@ -227,11 +233,11 @@ set(C_FLAGS_PROCESSOR " ${C_FLAGS_PROCESSOR} ${CFLAGS_PROCESSOR_USER}") Message("C_FLAGS_PROCESSOR is ${C_FLAGS_PROCESSOR}") -if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86") - if ( (NOT( C_FLAGS_PROCESSOR MATCHES "ssse3")) OR (NOT( C_FLAGS_PROCESSOR MATCHES "msse4.1")) ) - Message(FATAL_ERROR "For x86 Architecture, you must have following flags: -mssse3 -msse4.1. The current detected flags are: ${C_FLAGS_PROCESSOR}. You can pass the flags manually in build script, for example: ./build_oai --cflags_processor \"-mssse3 -msse4.1 -mavx2\" ") - endif() -endif() +#if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86") +# if ( (NOT( C_FLAGS_PROCESSOR MATCHES "ssse3")) OR (NOT( C_FLAGS_PROCESSOR MATCHES "msse4.1")) ) +# Message(FATAL_ERROR "For x86 Architecture, you must have following flags: -mssse3 -msse4.1. The current detected flags are: ${C_FLAGS_PROCESSOR}. You can pass the flags manually in build script, for example: ./build_oai --cflags_processor \"-mssse3 -msse4.1 -mavx2\" ") +# endif() +#endif() # # add autotools definitions that were maybe used! @@ -250,6 +256,22 @@ add_boolean_option(SANITIZE_ADDRESS False "enable the address sanitizer (ASan)") if (SANITIZE_ADDRESS) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer -fno-common") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -fno-common") + # There seems to be some incompatibility with pthread_create and the RT scheduler, which + # results in pthread_create hanging. + # + # When we switch from Ubuntu 16.04 to 18.04, we found that running with the address sanitizer, + # the pthread_create function calls were not working. The inital thought was that we were + # trying to create a thread that was not-blocking and would eventually crash the machine during + # the run. After more debugging, we found that we would never even start the thread. We narrowed + # down the first two instances of pthread_create in the gNB and NR UE to be sctp_eNB_task and + # one_thread, respectively. We found that adding sleeps, and various other pauses to the threads + # had not effect. From there, we found that if we add an abort(); prior to the thread loop, we + # do not execute that. This indicated to us that the problem is not likely to be a non-blocking + # thread, but perhaps and issue with pthread_create itself. From there we begain to research the + # issue on the web. See: https://github.com/google/sanitizers/issues/1125 + # + # Google searching indicates this appears to be a problem since at least 2018. This could be something + # wrong in the pthread library, or something subtly wrong in this CMakeLists.txt. Use Ubuntu 20.04 instead. endif () add_definitions("-DASN_DISABLE_OER_SUPPORT") @@ -1409,8 +1431,11 @@ set(PHY_NR_CODINGIF ) add_library(ldpc_orig MODULE ${PHY_LDPC_ORIG_SRC} ) +target_link_libraries(ldpc_orig PRIVATE ldpc_gen_HEADERS) add_library(ldpc_optim MODULE ${PHY_LDPC_OPTIM_SRC} ) +target_link_libraries(ldpc_optim PRIVATE ldpc_gen_HEADERS) add_library(ldpc_optim8seg MODULE ${PHY_LDPC_OPTIM8SEG_SRC} ) +target_link_libraries(ldpc_optim8seg PRIVATE ldpc_gen_HEADERS) add_library(ldpc_cl MODULE ${PHY_LDPC_CL_SRC} ) target_link_libraries(ldpc_cl OpenCL) add_dependencies(ldpc_cl nrLDPC_decoder_kernels_CL) @@ -1422,6 +1447,7 @@ if (CUDA_FOUND) endif (CUDA_FOUND) add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} ) +target_link_libraries(ldpc PRIVATE ldpc_gen_HEADERS) add_library(coding MODULE ${PHY_TURBOSRC} ) @@ -3189,3 +3215,4 @@ ADD_CUSTOM_TARGET(oarf ) include (${OPENAIR_DIR}/common/utils/telnetsrv/telnetsrv_CMakeLists.txt) +include(${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/CMakeLists.txt) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 1fdc3446d9..61b5b8ba95 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1105,7 +1105,8 @@ (Test20: Mapping type B, 4 DMRS Symbols), (Test21: 4x4 MIMO, 1 Layer), (Test22: 4x4 MIMO, 2 Layers), - (Test23: 25 PRBs, 15 kHz SCS) + (Test23: 25 PRBs, 15 kHz SCS) + (Test24: MCS 0, low SNR performance) $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c @@ -1134,8 +1135,9 @@ -n100 -s2 -U 2 1 3 -n10 -s20 -U 3 0 0 2 -gR -x1 -y4 -z4 -n10 -s20 -U 3 0 0 2 -gR -x2 -y4 -z4 - -n100 -m0 -e0 -R25 -b25 -i 2 1 0 - 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 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21 nr_dlsim.test22 nr_dlsim.test23 + -n100 -m0 -e0 -R25 -b25 -i 2 1 0 + -n100 -e0 -t95 -S-1.0 -i 2 1 0 + 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 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21 nr_dlsim.test22 nr_dlsim.test23 nr_dlsim.test24 PDSCH test OK segmentation fault|assertion|exiting|fatal 3 @@ -1314,7 +1316,8 @@ (Test18: 25 PRBs, 15 kHz SCS), (Test19: 3GPP G-FR1-A4-13 2 RX Antennas Requirements Test), (Test20: 3GPP G-FR1-A4-13 4 RX Antennas Requirements Test), - (Test21: 3GPP G-FR1-A4-13 8 RX Antennas Requirements Test) + (Test21: 3GPP G-FR1-A4-13 8 RX Antennas Requirements Test), + (Test22: MCS 0, low SNR performance) $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c @@ -1341,9 +1344,9 @@ -n100 -u0 -m0 -R25 -r25 -i 2 1 0 -m16 -r106 -s8.8 -S9.4 -z2 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0 -m16 -r106 -s5.4 -S6 -z4 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0 - -m16 -r106 -s3.4 -S3.8 -z8 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0 - - nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 nr_ulsim.test16 nr_ulsim.test17 nr_ulsim.test18 nr_ulsim.test19 nr_ulsim.test20 nr_ulsim.test21 + -m16 -r106 -s3.4 -S3.8 -z8 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0 + -n100 -m0 -S -0.6 -i 2 1 0 + nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 nr_ulsim.test16 nr_ulsim.test17 nr_ulsim.test18 nr_ulsim.test19 nr_ulsim.test20 nr_ulsim.test21 nr_ulsim.test22 PUSCH test OK segmentation fault|assertion|exiting|fatal 3 diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 6e788c9676..5a201fcfef 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -55,6 +55,7 @@ BUILD_COVERITY_SCAN=0 DISABLE_HARDWARE_DEPENDENCY="False" CMAKE_BUILD_TYPE="RelWithDebInfo" CMAKE_CMD="$CMAKE" +NOAVX512="False" BUILD_ECLIPSE=0 NR="False" OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope" @@ -164,6 +165,8 @@ Options: Build optional shared library, can be one or several of $OPTIONAL_LIBRARIES or \"all\" --usrp-recplay Build for I/Q record-playback modes +--noavx512 + Build without AVX512 if it is present on CPU -k | --skip-shared-libraries Skip build for shared libraries to reduce compilation time when building frequently for debugging purposes --ninja @@ -436,6 +439,10 @@ function main() { fi fi shift 2;; + --noavx512) + NOAVX512="True" + echo_info "Disabling AVX512" + shift 1;; -k | --skip-shared-libraries) SKIP_SHARED_LIB_FLAG="True" echo_info "Skipping build of shared libraries, rfsimulator and transport protocol libraries" @@ -445,6 +452,7 @@ function main() { MAKE_CMD=ninja shift;; --sanitize-address | -fsanitize=address) + grep -sq "Ubuntu 18.04" /etc/os-release && echo_error "Bug in OS with this option, see CMakeLists.txt" CMAKE_CMD="$CMAKE_CMD -DSANITIZE_ADDRESS=True" shift;; --ittiSIM) @@ -624,6 +632,7 @@ function main() { cd $DIR/$BUILD_DIR/build if [[ ${#CMAKE_C_FLAGS[@]} > 0 ]]; then CMAKE_CMD="$CMAKE_CMD -DCMAKE_C_FLAGS=\"${CMAKE_C_FLAGS[*]}\""; fi if [[ ${#CMAKE_CXX_FLAGS[@]} > 0 ]]; then CMAKE_CMD="$CMAKE_CMD -DCMAKE_CXX_FLAGS=\"${CMAKE_CXX_FLAGS[*]}\""; fi + CMAKE_CMD="$CMAKE_CMD -DNOAVX512=\"${NOAVX512[*]}\"" echo_info "running $CMAKE_CMD" eval $CMAKE_CMD ../.. diff --git a/docker/Dockerfile.build.rhel8.2 b/docker/Dockerfile.build.rhel8.2 index 22486c5e68..2664096a9b 100644 --- a/docker/Dockerfile.build.rhel8.2 +++ b/docker/Dockerfile.build.rhel8.2 @@ -35,4 +35,4 @@ COPY . . RUN /bin/sh oaienv && \ cd cmake_targets && \ mkdir -p log && \ - ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci + ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci --noavx512 diff --git a/docker/Dockerfile.build.ubuntu18 b/docker/Dockerfile.build.ubuntu18 index 3ba1e41442..7809d56216 100644 --- a/docker/Dockerfile.build.ubuntu18 +++ b/docker/Dockerfile.build.ubuntu18 @@ -35,4 +35,4 @@ COPY . . RUN /bin/sh oaienv && \ cd cmake_targets && \ mkdir -p log && \ - ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci + ./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci --noavx512 diff --git a/docker/Dockerfile.phySim.rhel8.2 b/docker/Dockerfile.phySim.rhel8.2 index 2627a9eafd..b4eb9a1eeb 100644 --- a/docker/Dockerfile.phySim.rhel8.2 +++ b/docker/Dockerfile.phySim.rhel8.2 @@ -38,7 +38,7 @@ RUN yum install -y libasan RUN /bin/sh oaienv && \ cd cmake_targets && \ mkdir -p log && \ - ./build_oai --phy_simulators --ninja --verbose-ci --sanitize-address + ./build_oai --phy_simulators --ninja --verbose-ci --sanitize-address --noavx512 #start from scratch for target executable FROM registry.access.redhat.com/ubi8/ubi:latest as oai-physim diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 007cf4e657..0a4a474a6c 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -209,6 +209,7 @@ extern int usrp_tx_thread; #define SOFTMODEM_NONBIOT_BIT (1<<2) #define SOFTMODEM_RFSIM_BIT (1<<10) #define SOFTMODEM_SIML1_BIT (1<<12) +#define SOFTMODEM_DLSIM_BIT (1<<13) #define SOFTMODEM_DOSCOPE_BIT (1<<15) #define SOFTMODEM_RECPLAY_BIT (1<<16) #define SOFTMODEM_TELNETCLT_BIT (1<<17) @@ -225,6 +226,7 @@ extern int usrp_tx_thread; #define IS_SOFTMODEM_NONBIOT ( get_softmodem_optmask() & SOFTMODEM_NONBIOT_BIT) #define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT) #define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT) +#define IS_SOFTMODEM_DLSIM ( get_softmodem_optmask() & SOFTMODEM_DLSIM_BIT) #define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT) #define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT) #define IS_SOFTMODEM_TELNETCLT_BIT ( get_softmodem_optmask() & SOFTMODEM_TELNETCLT_BIT) diff --git a/ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt b/ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt new file mode 100644 index 0000000000..2983268dac --- /dev/null +++ b/ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt @@ -0,0 +1,64 @@ +SNR BLER BER UNCODED_BER ENCODER_MEAN ENCODER_STD ENCODER_MAX DECODER_TIME_MEAN DECODER_TIME_STD DECODER_TIME_MAX DECODER_ITER_MEAN DECODER_ITER_STD DECODER_ITER_MAX +-2.000000 1.000000 0.346185 0.258473 44.551218 31.688925 357.883903 217.655668 12.810778 326.852166 5.000000 0.000000 5 +-1.900000 1.000000 0.345395 0.256275 40.787109 4.190954 65.926488 215.687102 4.300128 230.585721 5.000000 0.000000 5 +-1.800000 1.000000 0.343100 0.253634 40.748628 3.912915 56.669470 215.314020 4.139156 227.806468 5.000000 0.000000 5 +-1.700000 1.000000 0.341806 0.250634 40.550845 3.347808 56.032851 216.839001 5.959734 244.483352 5.000000 0.000000 5 +-1.600000 1.000000 0.339245 0.248129 40.457158 3.735092 56.853508 215.747244 4.995522 242.867659 5.000000 0.000000 5 +-1.500000 1.000000 0.337230 0.245763 41.178595 4.297429 56.265874 215.785600 4.151781 227.795995 5.000000 0.000000 5 +-1.400000 1.000000 0.335131 0.243311 39.915221 2.739586 55.454917 216.866764 6.547848 251.528327 5.000000 0.000000 5 +-1.300000 1.000000 0.333085 0.240664 40.119215 3.044973 55.978253 216.208443 4.459816 228.810686 5.000000 0.000000 5 +-1.200000 1.000000 0.330664 0.238769 40.507713 2.998241 55.701876 215.868796 3.778455 226.049304 5.000000 0.000000 5 +-1.100000 1.000000 0.329130 0.235812 41.038895 4.522472 56.760814 215.654663 4.746822 236.021980 5.000000 0.000000 5 +-1.000000 1.000000 0.325980 0.233534 41.067622 4.626711 57.444142 215.260535 3.481966 225.512853 5.000000 0.000000 5 +-0.900000 1.000000 0.323823 0.230863 40.683316 3.689159 56.208182 215.560917 5.180017 243.603452 5.000000 0.000000 5 +-0.800000 1.000000 0.321004 0.228222 41.643513 4.717568 58.502452 215.630891 4.283475 238.574145 5.000000 0.000000 5 +-0.700000 1.000000 0.317983 0.225520 41.214547 3.941824 56.054211 215.910346 4.375081 227.444626 5.000000 0.000000 5 +-0.600000 1.000000 0.316243 0.222903 40.834442 4.370416 56.765508 215.153296 3.617927 226.280086 5.000000 0.000000 5 +-0.500000 1.000000 0.312886 0.220473 40.178174 4.185502 64.657291 219.647151 4.454154 236.473446 5.000000 0.000000 5 +-0.400000 1.000000 0.309757 0.217536 40.240385 3.172484 55.751563 217.761119 3.900779 228.757195 5.000000 0.000000 5 +-0.300000 1.000000 0.305464 0.215229 40.852271 3.761739 56.158869 217.830497 4.087453 230.237764 5.000000 0.000000 5 +-0.200000 1.000000 0.302919 0.212364 40.531166 3.688281 56.426841 217.657657 5.498697 253.516146 5.000000 0.000000 5 +-0.100000 1.000000 0.298246 0.209310 41.058364 4.140510 59.959571 217.519279 4.087389 228.768313 5.000000 0.000000 5 +0.000000 1.000000 0.294110 0.207107 40.436486 3.604369 55.788895 217.853044 4.012624 236.118036 5.000000 0.000000 5 +0.100000 1.000000 0.288139 0.204033 40.603738 4.045866 57.560760 217.046816 4.583841 244.429411 5.000000 0.000000 5 +0.200000 1.000000 0.285604 0.201954 40.494607 3.886199 59.431970 217.322824 4.080988 233.317513 5.000000 0.000000 5 +0.300000 1.000000 0.278478 0.198929 40.311327 3.452837 56.124657 217.319394 4.434358 232.534720 5.000000 0.000000 5 +0.400000 1.000000 0.270992 0.196299 40.649243 3.415612 56.204178 218.079445 4.990947 245.055337 5.000000 0.000000 5 +0.500000 1.000000 0.263944 0.193661 40.464299 3.622703 56.602842 218.555364 3.936432 229.481159 5.000000 0.000000 5 +0.600000 1.000000 0.256340 0.191194 40.200314 2.474984 53.432412 216.547260 3.695211 227.198078 5.000000 0.000000 5 +0.700000 1.000000 0.251578 0.188606 40.111945 3.029821 54.900896 216.581752 4.247622 237.358365 5.000000 0.000000 5 +0.800000 1.000000 0.234558 0.184742 39.533282 1.182169 42.753097 215.462335 2.960246 226.716604 5.000000 0.000000 5 +0.900000 1.000000 0.225915 0.182691 39.851294 1.108193 42.180342 216.404194 4.450720 228.482353 5.000000 0.000000 5 +1.000000 1.000000 0.216180 0.179994 40.721936 3.302539 56.032206 217.082196 4.599188 227.979232 5.000000 0.000000 5 +1.100000 1.000000 0.203481 0.177332 41.006217 3.798207 56.014901 216.204345 4.292145 227.297386 5.000000 0.000000 5 +1.200000 1.000000 0.188297 0.174121 40.739289 3.269948 56.653507 216.585873 6.250858 251.207034 5.000000 0.000000 5 +1.300000 1.000000 0.172624 0.171622 41.215540 4.783342 55.692883 215.885639 3.629370 226.473280 5.000000 0.000000 5 +1.400000 1.000000 0.156483 0.169110 40.289903 3.749338 56.290861 215.663761 4.176366 225.824735 5.000000 0.000000 5 +1.500000 1.000000 0.136293 0.165692 42.208932 6.070189 69.182665 216.390504 4.816283 235.417446 5.000000 0.000000 5 +1.600000 1.000000 0.125127 0.163325 40.890581 3.941185 56.491504 215.752348 4.426511 226.425984 5.000000 0.000000 5 +1.700000 1.000000 0.104593 0.159971 41.263557 4.128935 57.062514 217.284932 5.311288 249.647163 5.000000 0.000000 5 +1.800000 1.000000 0.091397 0.157460 40.273078 3.062810 55.546913 217.252505 6.331426 251.175692 5.000000 0.000000 5 +1.900000 1.000000 0.078256 0.154628 40.407489 3.419342 56.316166 216.967648 4.712664 245.093313 5.000000 0.000000 5 +2.000000 1.000000 0.065221 0.152571 40.660365 4.317854 57.537407 216.198346 4.991856 245.173269 5.000000 0.000000 5 +2.100000 1.000000 0.053694 0.148885 40.355654 4.062614 60.051963 215.797667 4.447252 236.221454 5.000000 0.000000 5 +2.200000 1.000000 0.042182 0.146229 40.613562 4.124655 56.201536 216.117304 4.060825 227.115987 5.000000 0.000000 5 +2.300000 1.000000 0.034334 0.143612 40.465884 3.541452 55.067611 215.575953 4.891719 244.546802 5.000000 0.000000 5 +2.400000 1.000000 0.026641 0.140869 41.074690 4.697458 61.619188 216.069185 4.700827 233.830937 5.000000 0.000000 5 +2.500000 1.000000 0.019976 0.138112 40.766971 4.274128 58.871741 215.761570 5.633731 249.753931 5.000000 0.000000 5 +2.600000 1.000000 0.012826 0.135122 40.559343 2.952804 54.017706 215.835161 4.039993 226.822103 5.000000 0.000000 5 +2.700000 1.000000 0.010550 0.132915 40.985193 3.330639 55.013950 215.975836 4.240744 227.040703 5.000000 0.000000 5 +2.800000 1.000000 0.007327 0.130133 39.778804 3.002485 56.610555 216.462786 7.082268 265.051418 5.000000 0.000000 5 +2.900000 1.000000 0.004038 0.126763 40.327795 3.934211 55.515352 215.982666 4.626198 230.696124 5.000000 0.000000 5 +3.000000 1.000000 0.003087 0.124336 40.337807 3.537021 55.101627 215.468662 4.177203 230.789145 5.000000 0.000000 5 +3.100000 1.000000 0.001576 0.121689 39.812195 3.116738 55.422687 215.797778 4.091192 225.897780 5.000000 0.000000 5 +3.200000 0.980000 0.001000 0.118928 39.853764 2.871322 56.405555 215.562722 4.187466 232.598421 5.000000 0.000000 5 +3.300000 0.960000 0.000623 0.116065 40.440328 3.580650 56.738889 216.165848 4.735158 240.329999 5.000000 0.000000 5 +3.400000 0.850000 0.000303 0.113505 40.974107 4.291544 56.280236 215.889562 4.448049 237.556780 5.000000 0.000000 5 +3.500000 0.690000 0.000152 0.111010 41.508631 4.251791 56.198873 216.740295 4.889693 242.922934 5.000000 0.000000 5 +3.600000 0.530000 0.000102 0.108493 40.065231 3.643794 57.120823 216.887338 5.242621 250.003843 5.000000 0.000000 5 +3.700000 0.320000 0.000043 0.105612 40.462159 4.162383 56.782173 216.465615 3.846314 227.022697 5.000000 0.000000 5 +3.800000 0.210000 0.000032 0.103084 42.192455 6.207380 64.648964 217.030913 4.482820 228.095918 5.000000 0.000000 5 +3.900000 0.110000 0.000013 0.100391 40.640286 3.715782 55.922914 217.726055 4.553212 236.362804 5.000000 0.000000 5 +4.000000 0.050000 0.000006 0.097518 40.437760 2.838308 54.764308 218.230040 4.309275 237.932625 5.000000 0.000000 5 +4.100000 0.020000 0.000002 0.095436 41.347934 4.608500 64.182062 217.408836 4.385757 228.219627 5.000000 0.000000 5 +4.200000 0.000000 0.000000 0.092396 40.782371 3.621708 55.984245 217.579878 4.102149 228.145363 5.000000 0.000000 5 diff --git a/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/logo.png b/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/logo.png deleted file mode 100644 index 7b785ca051..0000000000 Binary files a/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/logo.png and /dev/null differ diff --git a/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/nrLDPC.pdf b/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/nrLDPC.pdf deleted file mode 100644 index 590dab5ce2..0000000000 Binary files a/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/nrLDPC.pdf and /dev/null differ diff --git a/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/nrLDPC.tex b/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/nrLDPC.tex deleted file mode 100644 index 019b51aa96..0000000000 --- a/openair1/PHY/CODING/nrLDPC_decoder/doc/nrLDPC/nrLDPC.tex +++ /dev/null @@ -1,960 +0,0 @@ -% -% Licensed to the OpenAirInterface (OAI) Software Alliance under one or more -% contributor license agreements. See the NOTICE file distributed with -% this work for additional information regarding copyright ownership. -% The OpenAirInterface Software Alliance licenses this file to You under -% the OAI Public License, Version 1.1 (the "License"); you may not use this file -% except in compliance with the License. -% You may obtain a copy of the License at -% -% http://www.openairinterface.org/?page_id=698 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, -% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -% See the License for the specific language governing permissions and -% limitations under the License. -%------------------------------------------------------------------------------- -% For more information about the OpenAirInterface (OAI) Software Alliance: -% contact@openairinterface.org -% - -\documentclass{article} - -\usepackage[a4paper, total={6in, 8in}]{geometry} - -\usepackage{amsmath} -\usepackage{amsfonts} -\usepackage{amssymb} -\usepackage{booktabs} -\usepackage{url} -\usepackage{tcolorbox} - -\usepackage{tikz} -\usetikzlibrary{arrows,decorations,shapes,backgrounds,patterns} -\usepackage{pgfplots} -\pgfplotsset{compat=newest} -\definecolor{green}{RGB}{32,127,43} -\usetikzlibrary{calc} - -\usepackage{listings} -\lstdefinestyle{customc}{ - belowcaptionskip=1\baselineskip, - breaklines=true, - frame=L, - xleftmargin=\parindent, - language=C, - showstringspaces=false, - basicstyle=\footnotesize\ttfamily, - keywordstyle=\bfseries\color{green!40!black}, - commentstyle=\itshape\color{purple!40!black}, - identifierstyle=\color{blue}, - stringstyle=\color{orange}, -} -\lstset{escapechar=@,style=customc} - -\title{NR LDPC Decoder} -\author{Sebastian Wagner (TCL)} -\date{\today} - -\def\0{\mathbf{0}} -\def\b{\mathbf{b}} -\def\Bbb{\mathbb{B}} -\def\Bcal{\mathcal{B}} -\def\c{\mathbf{c}} -\def\C{\mathbf{C}} -\def\Cbb{\mathbb{C}} -\def\Ccal{\mathcal{C}} -\def\eqdef{\triangleq} -\def\g{\mathbf{g}} -\def\G{\mathbf{G}} -\def\Gcal{\mathcal{G}} -\def\h{\mathbf{h}} -\def\H{\mathbf{H}} -\def\Hbg{\mathbf{H}_\mathrm{BG}} -\def\Hbgo{\mathbf{H}_\mathrm{BG1}} -\def\Hbgt{\mathbf{H}_\mathrm{BG2}} -\def\I{\mathbf{I}} -\def\Kb{{K_b}} -\def\m{\mathbf{m}} -\def\Mb{{M_b}} -\def\Nb{{N_b}} -\def\Nbb{\mathbb{N}} -\def\n{\mathbf{n}} -\def\nr{{n_{\rm r}}} -\def\nt{{n_{\rm t}}} -\def\s{\mathbf{s}} -\def\SNR{\mathsf{SNR}} -\def\y{\mathbf{y}} -\def\z{\mathbf{z}} -\def\Z{\mathbf{Z}} -\def\Zc{{Z_c}} - - -\def\herm{\mathsf{H}} -\def\trans{\mathsf{T}} -\def\EE{\mathsf{E}} -\newcommand{\sgn}{\operatorname{sgn}} - -\begin{document} - -\maketitle - -\begin{tikzpicture}[remember picture,overlay] - \node[anchor=north west,inner sep=0pt] at (current page.north west) - {\includegraphics[scale=0.5]{logo.png}}; -\end{tikzpicture} - - -\begin{center}Currently Supported:\end{center} -\tcbox[center]{ - \begin{tabular}{lll} - \toprule - \textbf{BG} & \textbf{Lifting Size Z} & \textbf{Code Rate R} \\ - \midrule - 1 & all & 1/3, 2/3, 8/9 \\ - 2 & all & 1/5, 1/3, 2/3 \\ - \bottomrule - \end{tabular} -} - -\paragraph{Version 1.0:} -\begin{itemize} -\item Initial version -\end{itemize} - -\paragraph{Version 2.0:} -\begin{itemize} -\item Enhancements in message passing: - \begin{itemize} - \item LUTs replaced by smaller BG-specific parameters - \item Inefficient load/store replaced by circular memcpy - \end{itemize} -\item Bug fixes: - \begin{itemize} - \item Fixed bug in function \texttt{llr2CnProcBuf} - \item Corrected input LLR dynamic range in BLER simulations - \end{itemize} -\item Results: - \begin{itemize} - \item Size of LUTs reduced significantly (60MB to 200KB) - \item Siginifcantly enhances execution time (factor 3.5) - \item Improved BLER performance (all simulation results have been updated) - \end{itemize} -\end{itemize} - - -\newpage -\tableofcontents - -\newpage -\section{Introduction} -\label{sec:introduction} - -Low Density Parity Check (LDPC) codes have been developed by Gallager in 1963 \cite{gallager1962low}. They are linear error correcting codes that are capacity-achieving for large block length and are completely described by their Parity Check Matrix (PCM) $\H^{M\times N}$. The PCM $\H$ defines $M$ constraints on the codeword $\c$ of length $N$ such that -\begin{equation} - \label{eq:29} - \H\c = \0. -\end{equation} -The number of information bits $B$ that can be encoded with $\H$ is given by $B=N-M$. Hence the code rate $R$ of $\H$ reads -\begin{equation} - \label{eq:37} - R = \frac{B}{N} = 1-\frac{M}{N}. -\end{equation} - - -\subsection{LDPC in NR} -\label{sec:ldpc-nr} - -NR uses quasi-cyclic (QC) Protograph LDPC codes, i.e. a smaller graph, called Base Graph (BG), is defined and utilized to construct the larger PCM. This has the advantage that the large PCM does not have to be stored in memory and allows for a more efficient implementation while maintaining good decoding properties. -Two BGs $\Hbg\in\Nbb^{\Mb\times \Nb}$ are defined in NR: -\begin{enumerate} -\item $\Hbgo\in\Nbb^{46\times 68}$ -\item $\Hbgt\in\Nbb^{42\times 52}$ -\end{enumerate} -where $\Nbb$ is the set of integers. For instance the first 3 rows and 13 columns of BG2 are given by - -\setcounter{MaxMatrixCols}{30} -\begin{equation*} - \label{eq:33} - \Hbgt = - \begin{bmatrix} - 9 & 117 & 204 & 26 & \emptyset & \emptyset & 189 & \emptyset & \emptyset & 205 & 0 & 0 & \emptyset & \emptyset \\ - 127 & \emptyset & \emptyset & 166 & 253 & 125 & 226 & 156 & 224 & 252 & \emptyset & 0 & 0 & \emptyset \\ - 81 & 114 & \emptyset & 44 & 52 & \emptyset & \emptyset & \emptyset & 240 & \emptyset & 1 & \emptyset & 0 & 0 - \end{bmatrix}. -\end{equation*} - -To obtain the PCM $\H$ from the BG $\Hbg$, each element $\Hbg(i,j)$ in the BG is replaced by a lifting matrix of size $\Zc\times \Zc$ according to -\begin{equation} - \label{eq:35} - \Hbg(i,j) = - \begin{cases} - \0 & \textrm{if}~ \Hbg(i,j)=\emptyset \\ - \I_{P_{ij}} & \textrm{otherwise} - \end{cases} -\end{equation} -where $\I_{P_{ij}}$ is the identity matrix circularly shifted to the right by $P_{ij} = \Hbg(i,j)\mod \Zc$. Hence, the resulting PCM $\H$ will be of size $\Mb\Zc\times\Nb\Zc$. - -The lifting size $\Zc$ depends on the number of bits to encode. To limit the complexity, a discrete set $\mathcal{Z}$ of possible values of $\Zc$ has been defined in \cite{3gpp2017_38212} and the optimal value $\Zc$ is calculated according to -\begin{equation} - \label{eq:36} - \Zc = \min_{\Z\in\mathcal{Z}}\left[Z\geq\frac{B}{\Nb}\right]. -\end{equation} - -The base rate of the two BGs is $1/3$ and $1/5$ for BG1 and BG2, respectively. That is, BG1 encodes $K=22\Zc$ bits and BG2 encodes $K=10\Zc$ bits. Note that the first 2 columns of BG 1 and 2 are always punctured, that is after encoding, the first $2\Zc$ bits are discarded and not transmitted. -For instance, consider $B=500$ information bits to encode using BG2, \eqref{eq:36} yields $\Zc=64$ hence $K=640$. Since $K>B$, $K-B=140$ filler bits are appended to the information bits. The PCM $\Hbgt$ is of size $2688\times 3328$ and the $640$ bits $\b$ are encoded according to \eqref{eq:29} at a rate $R \approx 0.192$. To achieve the higher base rate of $0.2$, the first $128$ are punctured, i.e. instead of transmitting all $3328$ bits, only $3200$ are transmitted resulting in the desired rate $R=640/3200=0.2$. - -\subsection{LDPC Decoding} -\label{sec:ldpc-decoding} - -The decoding of codeword $\c$ can be achieved via the classical message passing algorithm. This algorithm can be illustrated best using the Tanner graph of the PCM. The rows of the PCM are called check nodes (CN) since they represent the parity check equations. The parity check equation of each of these check nodes involves various bits in the codeword. Similarly, every column of the PCM corresponds to a bit and each bit is involved in several parity check equations. In the Tanner graph representation, the bits are called bit nodes (BN). Let's go back to the previous example of BG2 and assume $\Zc=2$, hence the first 3 rows and 13 columns of BG2 $\Hbgt$ read -\begin{equation*} - \label{eq:36} - \Hbgt = - \begin{bmatrix} - 1 & 1 & 0 & 0 & \emptyset & \emptyset & 1 & \emptyset & \emptyset & 1 & 0 & 0 & \emptyset & \emptyset \\ - 1 & \emptyset & \emptyset & 0 & 1 & 1 & 0 & 0 & 0 & 0 & \emptyset & 0 & 0 & \emptyset \\ - 1 & 0 & \emptyset & 0 & 0 & \emptyset & \emptyset & \emptyset & 0 & \emptyset & 1 & \emptyset & 0 & 0 - \end{bmatrix}. -\end{equation*} -Replacing the elements according to \eqref{eq:35}, we obtain the first 6 rows and 26 columns of the PCM as -\begin{equation*} - \label{eq:39} - \H = - \begin{bmatrix} - 0 & 1 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\ - 1 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0\\ - 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0\\ - 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0\\ - 0 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0\\ - 1 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 1 - \end{bmatrix}. -\end{equation*} - -The Tanner graph of the first 8 BNs is shown in Figure \ref{fig:tannergraph}. - -\begin{figure}[ht] - \label{fig:tannergraph} - \centering - \def\ww{0.3cm} - \def\hh{0.3cm} - \tikzstyle{cnode}=[fill=white,rectangle,draw=black,thick,inner sep=2pt, minimum height=\hh,minimum width=\ww, rounded corners=1pt,text width=\ww] - \tikzstyle{vnode}=[fill=white,circle,draw=black,thick,inner sep=2pt, minimum height=\hh,minimum width=\ww, rounded corners=1pt,text width=\ww] - \tikzstyle{connector}=[<->,>=latex',semithick] - - \begin{tikzpicture} - \tikzstyle{every node}=[node distance=1.5cm,text centered] - % Check nodes - \node[cnode, label=above:$v_0$] (v0) {}; - \node[cnode, label=above:$v_1$, right of=v0] (v1) {}; - \node[cnode, label=above:$v_2$, right of=v1] (v2) {}; - % Variable nodes - \node[vnode, label=below:$c_3$, below of=v1, node distance=1.5cm] (c3) {}; - \node[vnode, label=below:$c_2$, left of=c3, node distance=1.5cm] (c2) {}; - \node[vnode, label=below:$c_1$, left of=c2, node distance=1.5cm] (c1) {}; - \node[vnode, label=below:$c_0$, left of=c1, node distance=1.5cm] (c0) {}; - \node[vnode, label=below:$c_4$, right of=c3, node distance=1.5cm] (c4) {}; - \node[vnode, label=below:$c_5$, right of=c4, node distance=1.5cm] (c5) {}; - \node[vnode, label=below:$c_6$, right of=c5, node distance=1.5cm] (c6) {}; - - % Draw edges - \draw (c0) edge[connector] (v1); - \draw (c1) edge[connector] (v0); - \draw (c1) edge[connector] (v2); - \draw (c2) edge[connector] (v1); - \draw (c3) edge[connector] (v0); - \draw (c4) edge[connector] (v0); - \draw (c4) edge[connector] (v2); - \draw (c5) edge[connector] (v1); - \draw (c6) edge[connector] (v0); - \draw (c6) edge[connector] (v2); - - \end{tikzpicture} - - \caption{Tanner graph for first 7 bits nodes and 3 check nodes from \eqref{eq:39}.} -\end{figure} - -The message passing algorithm is an iterative algorithm where probabilities of the bits (being either 0 or 1) are exchanged between the BNs and CNs. After sufficient iterations, the probabilities will have either converged to either 0 or 1 and the parity check equations will be satisfied, at this point, the codeword has been decoded correctly. - -\newpage -\section{LDPC Decoder Implementation} -\label{sec:ldpc-implementation} - -The implementation on a general purpose processor (GPP) has to take advantage of potential instruction extension of the processor architecture. We focus on the Intel x86 instruction set architecture (ISA) and its advanced vector extension (AVX). In particular, we utilize AVX2 with its 256-bit single instruction multiple data (SIMD) format. In order to utilize AVX2 to speed up the processing at the CNs and BNs, the corresponding data has to be ordered/aligned in a specific way. The processing flow of the LDPC decoder is depicted in \ref{fig:ldpc_decoder_flow}. - -\begin{figure}[ht] - \label{fig:ldpc_decoder_flow} - \centering - \def\ww{0.3cm} - \def\hh{0.3cm} - \tikzstyle{func}=[,draw=none] - \tikzstyle{connector}=[->,>=latex',semithick] - - \begin{tikzpicture} - \tikzstyle{every node}=[node distance=2.5cm,text centered] - % Check nodes - % First iteration - \node[func] (llr2llrProcBuf) {\texttt{llr2llrProcBuf}}; - \node[func, above of=llr2llrProcBuf] (llr2CnProcBuf) {\texttt{llr2CnProcBuf}}; - \node[func, above right of=llr2CnProcBuf] (cnProc1) {\texttt{cnProc}}; - \node[func, below right of=cnProc1] (cn2bnProcBuf1) {\texttt{cn2bnProcBuf}}; - \node[func, below of=cn2bnProcBuf1] (bnProcPc1) {\texttt{bnProcPc}}; - - % Iterations - \node[func, right of=cnProc1, node distance=7cm] (cnProc) {\texttt{cnProc}}; - \node[func, below right of=cnProc] (cn2bnProcBuf) {\texttt{cn2bnProcBuf}}; - \node[func, below of=cn2bnProcBuf] (bnProcPc) {\texttt{bnProcPc}}; - \node[func, below left of=cnProc] (bn2cnProcBuf) {\texttt{bn2cnProcBuf}}; - \node[func, below of=bn2cnProcBuf] (bnProc) {\texttt{bnProc}}; - - % Post processing - \node[func, below of=bnProcPc] (llrRes2llrOut) {\texttt{llrRes2llrOut}}; - \node[func, below of=llrRes2llrOut, node distance=1cm] (llr2bit) {\texttt{llr2bit}}; - - % Draw edges - \draw (llr2llrProcBuf) edge[connector] (llr2CnProcBuf); - \draw (llr2CnProcBuf) edge[connector] (cnProc1); - \draw (cnProc1) edge[connector] (cn2bnProcBuf1); - \draw (cn2bnProcBuf1) edge[connector] (bnProcPc1); - - \draw (bnProcPc) edge[connector] (bnProc); - \draw (bnProc) edge[connector] (bn2cnProcBuf); - \draw (bn2cnProcBuf) edge[connector] node[above left] {\texttt{cnProcPc}} (cnProc); - \draw (cnProc) edge[connector] (cn2bnProcBuf); - \draw (cn2bnProcBuf) edge[connector] (bnProcPc); - - \draw (bnProcPc1) edge[connector] (bnProc); - - \draw (bnProcPc) edge[connector] node[left] {iterations done} (llrRes2llrOut); - \draw (llrRes2llrOut) edge[connector] (llr2bit); - - % Boxes - \node[inner sep=0pt,above right of=cn2bnProcBuf1, node distance = 2.5cm] (ref) {}; - - \draw[fill=black,opacity=.2, rounded corners] (llr2llrProcBuf.south west) rectangle ($(ref) + (-.5cm,.5cm)$); - \draw[fill=black,opacity=.2, rounded corners] ($(ref) + (.5cm,.5cm)$) rectangle ($(bnProcPc.south east) + (.4cm,0)$); - - \node[func, above of=cnProc1, node distance=.8cm] (iter1) {\textbf{First Iteration}}; - \node[func, above of=cnProc , node distance=.8cm] (iterX) {\textbf{Subsequent Iterations}}; - - \end{tikzpicture} - - \caption{LDPC Decoder processing flow.} -\end{figure} - -The functions involved are described in more detail in Table \ref{tab:sum_func}. - -\begin{table}[ht] - \centering - \begin{tabular}{ll} - \toprule - \textbf{Function} & \textbf{Description} \\ - \midrule - \texttt{llr2llrProcBuf} & Copies input LLRs to LLR processing buffer \\ - \texttt{llr2CnProcBuf} & Copies input LLRs to CN processing buffer \\ - \texttt{cnProc} & Performs CN signal processing \\ - \texttt{cnProcPc} & Performs parity check \\ - \texttt{cn2bnProcBuf} & Copies the CN results to the BN processing buffer \\ - \texttt{bnProcPc} & Performs BN processing for parity check and/or hard-decision \\ - \texttt{bnProc} & Utilizes the results of \texttt{bnProcPc} to compute LLRs for CN processing \\ - \texttt{bn2cnProcBuf} & Copies the BN results to the CN processing buffer \\ - \texttt{llrRes2llrOut} & Copies the results of \texttt{bnProcPc} to output LLRs \\ - \texttt{llr2bit} & Performs hard-decision on the output LLRs \\ - \bottomrule - \end{tabular} - \caption{Summary of the LDPC decoder functions.} - \label{tab:sum_func} -\end{table} - -The input LLRs are assumed to be 8-bit and aligned on 32 bytes. CN processing is carried out in 8-bit whereas BN processing is done in 16 bit. Subsequently, the processing tasks at the CNs and BNs are explained in more detail. - -\newpage -\subsection{Check Node Processing} -\label{sec:check-node-proc} - -Denote $q_{ij}$ the value from BN $j$ to CN $i$ and let $\Bcal_i$ be the set of connected BNs to the $i$th CN. Then, using the min-sum approximation, CN $i$ has to carry out the following operation for each connected BN. -\begin{equation} - \label{eq:40} - r_{ji} = \prod_{j'\in\Bcal_i\setminus j}\sgn q_{ij'}\min_{j'\in\Bcal_i\setminus j} |q_{ij'}| -\end{equation} -where $r_{ji}$ is the value returned to BN $j$ from CN $i$. There are $\Mb = \{46,42\}$ CNs in BG 1 and BG 2, respectively. Each of these CNs is connected to only a small number of BNs. The number of connected BNs to CN $i$ is $|\Bcal_i|$. In BG1 and BG2, $|\Bcal_i|=\{3,4,5,6,7,8,9,10,19\}$ and $|\Bcal_i|=\{3,4,5,6,8,10\}$, respectively. The following tables show the number of CNs $M_{|\Bcal_i|}$ that are connected to the same number of BNs. - -\begin{table}[ht] - \centering - \begin{tabular}{llllllllll} - \toprule - $|\Bcal_i|$ & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 19 \\ - \midrule - $M_{|\Bcal_i|}^\mathrm{BG1}$ & 1 & 5 &18 & 8 & 5 & 2 & 2 & 1 & 4 \\ - $M_{|\Bcal_i|}^\mathrm{BG2}$ & 6 & 20 & 9 & 3 & 0 & 2 & 0 & 2 & 0 \\ - \bottomrule - \end{tabular} - \caption{Ceck node groups for BG1 and BG2.} - \label{tab:checkNodeGroups} -\end{table} - -It can be observed that each CN is at least connected to 3 BNs and there are 9 groups and 5 groups in BG1 and BG2, respectively. Denote the set of CN groups as $\Gcal$ and $M_k$ the number of CNs in group $k\in\Gcal$, e.g. for BG2 $M_4=20\Zc$. Each CN group will be processed separately. The CN processing buffer $p_C^k$ of group $k$ is defined as -\begin{equation} - \label{eq:44} - p_C^k = \{\underbrace{q_{11}q_{21}\dots q_{M_k 1}}_{\text 1. BN},\underbrace{q_{12}q_{22}\dots q_{M_k 2}}_{\text 2. BN},\dots,\underbrace{q_{12}q_{22}\dots q_{M_k k}}_{\text last BN}\} -\end{equation} -Hence, $|p_C^k| = kM_k$, e.g, $\Zc=128$, $|p_C^4| = 4\cdot 20\cdot 128 = 10240$. - -\begin{lstlisting}[frame=single,caption={Example of CN processing for group 3 from \texttt{cnProc}.},label=code_cnproc] % Start your code-block - - const uint8_t lut_idxCnProcG3[3][2] = {{72,144}, {0,144}, {0,72}}; - - // ===================================================================== - // Process group with 3 BNs - - // Number of groups of 32 CNs for parallel processing - M = (lut_numCnInCnGroups[0]*Z)>>5; - // Set the offset to each bit within a group in terms of 32 Byte - bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[0]*NR_LDPC_ZMAX)>>5; - - // Set pointers to start of group 3 - p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[0]]; - p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[0]]; - - // Loop over every BN - for (j=0; j<3; j++) - { - // Set of results pointer to correct BN address - p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup); - - // Loop over CNs - for (i=0; i>5; - - // Set the offset to each CN within a group in terms of 16 Byte - cnOffsetInGroup = (lut_numBnInBnGroups[2]*NR_LDPC_ZMAX)>>4; - - // Set pointers to start of group 3 - p_bnProcBuf = (__m128i*) &bnProcBuf [lut_startAddrBnGroups [idxBnGroup]]; - p_llrProcBuf = (__m128i*) &llrProcBuf [lut_startAddrBnGroupsLlr[idxBnGroup]]; - p_llrRes = (__m256i*) &llrRes [lut_startAddrBnGroupsLlr[idxBnGroup]]; - - // Loop over BNs - for (i=0,j=0; i