diff --git a/CMakeLists.txt b/CMakeLists.txt index 28d6e31572..a024b594d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1015,6 +1015,10 @@ endif() add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} ) target_link_libraries(ldpc PRIVATE ldpc_gen_HEADERS) +add_library(ldpc_parityCheck MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} ) +target_compile_definitions(ldpc_parityCheck PUBLIC NR_LDPC_ENABLE_PARITY_CHECK) +target_link_libraries(ldpc_parityCheck PRIVATE ldpc_gen_HEADERS) + add_library(coding MODULE ${PHY_TURBOSRC} ) add_library(dfts MODULE ${OPENAIR1_DIR}/PHY/TOOLS/oai_dfts.c ) @@ -2408,7 +2412,7 @@ add_executable(ldpctest ${SHLIB_LOADER_SOURCES} ) -add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) +add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc ldpc_parityCheck) if (ENABLE_LDPC_CUDA) add_dependencies(ldpctest ldpc_cuda) endif() diff --git a/common/utils/load_module_shlib.c b/common/utils/load_module_shlib.c index fe7356de9d..a43594cb9a 100644 --- a/common/utils/load_module_shlib.c +++ b/common/utils/load_module_shlib.c @@ -63,60 +63,55 @@ void loader_init(void) { } /* build the full shared lib name from the module name */ -char *loader_format_shlibpath(char *modname, char *version) +static char *loader_format_shlibpath(char *modname, char *version) { - -char *tmpstr; -char *shlibpath =NULL; -char *shlibversion=NULL; -// clang-format off -paramdef_t LoaderParams[] = { + char *tmpstr; + char *shlibpath = NULL; + char *shlibversion = NULL; + // clang-format off + paramdef_t LoaderParams[] = { {"shlibpath", NULL, 0, .strptr = &shlibpath, .defstrval = NULL, TYPE_STRING, 0, NULL}, {"shlibversion", NULL, 0, .strptr = &shlibversion, .defstrval = "", TYPE_STRING, 0, NULL} -}; -// clang-format on + }; + // clang-format on -int ret; + int ret; - - - -/* looks for specific path for this module in the config file */ -/* specific value for a module path and version is located in a modname subsection of the loader section */ -/* shared lib name is formatted as lib.so */ + /* looks for specific path for this module in the config file */ + /* specific value for a module path and version is located in a modname subsection of the loader section */ + /* shared lib name is formatted as lib.so */ char cfgprefix[sizeof(LOADER_CONFIG_PREFIX)+strlen(modname)+16]; sprintf(cfgprefix,LOADER_CONFIG_PREFIX ".%s",modname); - ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),cfgprefix); + ret = config_get(LoaderParams, sizeofArray(LoaderParams), cfgprefix); if (ret <0) { - fprintf(stderr,"[LOADER] %s %d couldn't retrieve config from section %s\n",__FILE__, __LINE__,cfgprefix); - } -/* no specific path, use loader default shared lib path */ - if (shlibpath == NULL) { - shlibpath = loader_data.shlibpath ; - } -/* no specific shared lib version */ - if (version != NULL) { // version specified as a function parameter - shlibversion=version; - } - if (shlibversion == NULL) { // no specific version specified, neither as a config param or as a function param - shlibversion = "" ; - } -/* alloc memory for full module shared lib file name */ - tmpstr = malloc(strlen(shlibpath)+strlen(modname)+strlen(shlibversion)+16); - if (tmpstr == NULL) { - fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno)); - exit_fun("[LOADER] unrecoverable error"); - } - if(shlibpath[0] != 0) { - ret=sprintf(tmpstr,"%s/",shlibpath); - } else { - ret = 0; - } + fprintf(stderr, "[LOADER] %s %d couldn't retrieve config from section %s\n", __FILE__, __LINE__, cfgprefix); + } + /* no specific path, use loader default shared lib path */ + if (shlibpath == NULL) { + shlibpath = loader_data.shlibpath; + } + /* no specific shared lib version */ + if (version != NULL) { // version specified as a function parameter + shlibversion = version; + } + if (shlibversion == NULL) { // no specific version specified, neither as a config param or as a function param + shlibversion = ""; + } + /* alloc memory for full module shared lib file name */ + tmpstr = malloc(strlen(shlibpath) + strlen(modname) + strlen(shlibversion) + 16); + if (tmpstr == NULL) { + fprintf(stderr, "[LOADER] %s %d malloc error loading module %s, %s\n", __FILE__, __LINE__, modname, strerror(errno)); + exit_fun("[LOADER] unrecoverable error"); + } + if (shlibpath[0] != 0) { + ret = sprintf(tmpstr, "%s/", shlibpath); + } else { + ret = 0; + } - sprintf(tmpstr+ret,"lib%s%s.so",modname,shlibversion); - - - return tmpstr; + sprintf(tmpstr + ret, "lib%s%s.so", modname, shlibversion); + + return tmpstr; } int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *farray, int numf, void *autoinit_arg) diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index 45bfb2cfd5..f4064fe844 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -435,7 +435,9 @@ int main(int argc, char *argv[]) unsigned int errors, errors_bit, crc_misses; double errors_bit_uncoded; short block_length=8448; // decoder supports length: 1201 -> 1280, 2401 -> 2560 - char *ldpc_version=NULL; /* version of the ldpc decoder library to use (XXX suffix to use when loading libldpc_XXX.so */ + // default to check output inside ldpc, the NR version checks the outer CRC defined by 3GPP + char *ldpc_version = "_parityCheck"; + /* version of the ldpc decoder library to use (XXX suffix to use when loading libldpc_XXX.so */ short max_iterations=5; int n_segments=1; //double rate=0.333; @@ -535,11 +537,7 @@ int main(int argc, char *argv[]) printf("n_trials %d: \n", n_trials); printf("SNR0 %f: \n", SNR0); - - if (ldpc_version != NULL) - load_nrLDPClib(ldpc_version); - else - load_nrLDPClib(NULL); + load_nrLDPClib(ldpc_version); load_nrLDPClib_ref("_orig", &encoder_orig); //for (block_length=8;block_length<=MAX_BLOCK_LENGTH;block_length+=8) diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h index 8956f31427..0b4e12ad5d 100644 --- a/openair1/PHY/CODING/coding_defs.h +++ b/openair1/PHY/CODING/coding_defs.h @@ -399,8 +399,8 @@ unsigned int crc8 (unsigned char * inptr, int bitlen); @param bitlen length of inputs in bits*/ unsigned int crc6 (unsigned char * inptr, int bitlen); -int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type); - +int check_crc(uint8_t *decoded_bytes, uint32_t n, uint8_t crc_type); + /*!\fn void phy_viterbi_dot11_sse2(int8_t *y, uint8_t *decoded_bytes, uint16_t n,int offset,int traceback) \brief This routine performs a SIMD optmized Viterbi decoder for the 802.11 64-state convolutional code. It can be run in segments with final trace back after last segment. diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c index 97853164f5..8248688b77 100644 --- a/openair1/PHY/CODING/crc_byte.c +++ b/openair1/PHY/CODING/crc_byte.c @@ -313,7 +313,7 @@ uint32_t crc6(unsigned char* inptr, int bitlen) return crc; } -int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type) +int check_crc(uint8_t* decoded_bytes, uint32_t n, uint8_t crc_type) { uint32_t crc=0,oldcrc=0; uint8_t crc_len=0; diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h index 09e15cea83..659144bce2 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h @@ -2728,41 +2728,25 @@ static inline void nrLDPC_bnProc(t_nrLDPC_lut* p_lut, int8_t* bnProcBuf, int8_t* */ static inline void nrLDPC_llr2bit(int8_t* out, int8_t* llrOut, uint16_t numLLR) { - __m256i* p_llrOut = (__m256i*) llrOut; - __m256i* p_out = (__m256i*) out; - int8_t* p_llrOut8; - int8_t* p_out8; - uint32_t i; - uint32_t M = numLLR>>5; - uint32_t Mr = numLLR&31; + __m256i* p_llrOut = (__m256i*)llrOut; + __m256i* p_out = (__m256i*)out; + const int M = numLLR >> 5; + const int Mr = numLLR & 31; - const __m256i* p_zeros = (__m256i*) zeros256_epi8; - const __m256i* p_ones = (__m256i*) ones256_epi8; + const __m256i* p_zeros = (__m256i*)zeros256_epi8; + const __m256i* p_ones = (__m256i*)ones256_epi8; - for (i=0; i 0) - { - // Remaining LLRs that do not fit in multiples of 32 bytes - p_llrOut8 = (int8_t*) p_llrOut; - p_out8 = (int8_t*) p_out; + // Remaining LLRs that do not fit in multiples of 32 bytes + int8_t* p_llrOut8 = (int8_t*)p_llrOut; + int8_t* p_out8 = (int8_t*)p_out; - for (i=0; i>5; - uint32_t Mr = numLLR&31; - const __m256i* p_shuffle = (__m256i*) constShuffle_256_epi8; + const uint32_t M = numLLR >> 5; + const uint32_t Mr = numLLR & 31; - for (i=0; i 0) - { - // Remaining LLRs that do not fit in multiples of 32 bytes - p_llrOut8 = (int8_t*) p_llrOut; - - for (i=0; i p_decParams->numMaxIter) - set_abort(ab, true); + // Launch LDPC decoder core for one segment + int numIter = nrLDPC_decoder_core(p_llr, p_out, numLLR, p_lut, p_decParams, p_profiler, ab); + if (numIter > p_decParams->numMaxIter) { + LOG_D(PHY, "set abort: %d, %d\n", numIter, p_decParams->numMaxIter); + set_abort(ab, true); + } return numIter; } @@ -179,48 +176,26 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t bnProcBuf[NR_LDPC_SIZE_BN_PROC_BUF] __attribute__ ((aligned(64))) = {0}; int8_t bnProcBufRes[NR_LDPC_SIZE_BN_PROC_BUF] __attribute__ ((aligned(64))) = {0}; int8_t llrRes[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(64))) = {0}; - int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(64))) = {0}; - int8_t llrOut[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(64))) = {0}; + int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__((aligned(64))) = {0}; // Minimum number of iterations is 1 // 0 iterations means hard-decision on input LLRs - uint32_t i = 1; // Initialize with parity check fail != 0 - int32_t pcRes = 1; - int8_t* p_llrOut; - - if (outMode == nrLDPC_outMode_LLRINT8) - { - p_llrOut = p_out; - } - else - { - // Use LLR processing buffer as temporary output buffer - p_llrOut = llrOut; - } - // Initialization -#ifdef NR_LDPC_PROFILER_DETAIL - start_meas(&p_profiler->llr2llrProcBuf); -#endif + NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->llr2llrProcBuf)); nrLDPC_llr2llrProcBuf(p_lut, p_llr, llrProcBuf, Z, BG); -#ifdef NR_LDPC_PROFILER_DETAIL - stop_meas(&p_profiler->llr2llrProcBuf); -#endif - + NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->llr2llrProcBuf)); #ifdef NR_LDPC_DEBUG_MODE nrLDPC_debug_initBuffer2File(nrLDPC_buffers_LLR_PROC); nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_LLR_PROC, llrProcBuf); #endif -#ifdef NR_LDPC_PROFILER_DETAIL - start_meas(&p_profiler->llr2CnProcBuf); -#endif - if (BG == 1) nrLDPC_llr2CnProcBuf_BG1(p_lut, p_llr, cnProcBuf, Z); - else nrLDPC_llr2CnProcBuf_BG2(p_lut, p_llr, cnProcBuf, Z); -#ifdef NR_LDPC_PROFILER_DETAIL - stop_meas(&p_profiler->llr2CnProcBuf); -#endif + NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->llr2CnProcBuf)); + if (BG == 1) + nrLDPC_llr2CnProcBuf_BG1(p_lut, p_llr, cnProcBuf, Z); + else + nrLDPC_llr2CnProcBuf_BG2(p_lut, p_llr, cnProcBuf, Z); + NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->llr2CnProcBuf)); #ifdef NR_LDPC_DEBUG_MODE nrLDPC_debug_initBuffer2File(nrLDPC_buffers_CN_PROC); @@ -230,12 +205,10 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, // First iteration // CN processing -#ifdef NR_LDPC_PROFILER_DETAIL - start_meas(&p_profiler->cnProc); -#endif + NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->cnProc)); if (BG==1) { -#ifndef UNROLL_CN_PROC - nrLDPC_cnProc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z); +#ifndef UNROLL_CN_PROC + nrLDPC_cnProc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z); #else switch (R) { @@ -307,23 +280,19 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, } #endif } -#ifdef NR_LDPC_PROFILER_DETAIL - stop_meas(&p_profiler->cnProc); -#endif + NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->cnProc)); #ifdef NR_LDPC_DEBUG_MODE nrLDPC_debug_initBuffer2File(nrLDPC_buffers_CN_PROC_RES); nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC_RES, cnProcBufRes); #endif -#ifdef NR_LDPC_PROFILER_DETAIL - start_meas(&p_profiler->cn2bnProcBuf); -#endif - if (BG == 1) nrLDPC_cn2bnProcBuf_BG1(p_lut, cnProcBufRes, bnProcBuf, Z); - else nrLDPC_cn2bnProcBuf_BG2(p_lut, cnProcBufRes, bnProcBuf, Z); -#ifdef NR_LDPC_PROFILER_DETAIL - stop_meas(&p_profiler->cn2bnProcBuf); -#endif + NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->cn2bnProcBuf)); + if (BG == 1) + nrLDPC_cn2bnProcBuf_BG1(p_lut, cnProcBufRes, bnProcBuf, Z); + else + nrLDPC_cn2bnProcBuf_BG2(p_lut, cnProcBufRes, bnProcBuf, Z); + NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->cn2bnProcBuf)); #ifdef NR_LDPC_DEBUG_MODE nrLDPC_debug_initBuffer2File(nrLDPC_buffers_BN_PROC); @@ -331,10 +300,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, #endif // BN processing -#ifdef NR_LDPC_PROFILER_DETAIL - start_meas(&p_profiler->bnProcPc); -#endif - + NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->bnProcPc)); #ifndef UNROLL_BN_PROC_PC nrLDPC_bnProcPc(p_lut, bnProcBuf, bnProcBufRes, llrProcBuf, llrRes, Z); @@ -379,18 +345,14 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, } #endif -#ifdef NR_LDPC_PROFILER_DETAIL - stop_meas(&p_profiler->bnProcPc); -#endif + NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->bnProcPc)); #ifdef NR_LDPC_DEBUG_MODE nrLDPC_debug_initBuffer2File(nrLDPC_buffers_LLR_RES); nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_LLR_RES, llrRes); #endif -#ifdef NR_LDPC_PROFILER_DETAIL - start_meas(&p_profiler->bnProc); -#endif + NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->bnProc)); if (BG==1) { #ifndef UNROLL_BN_PROC @@ -491,13 +453,16 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, // estimated after only one iteration // First iteration finished - - while ( (i < numMaxIter) && (pcRes != 0) ) { - // Increase iteration counter - i++; - if (check_abort(ab)) - return numMaxIter + 2; - // CN processing + uint32_t numIter = 1; + int32_t pcRes = 1; // pcRes is 0 if the ldpc decoder is succesful + while ((numIter <= numMaxIter) && (pcRes != 0)) { + // Increase iteration counter + numIter++; + if (check_abort(ab)) { + numIter = numMaxIter + 2; + break; + } + // CN processing #ifdef NR_LDPC_PROFILER_DETAIL start_meas(&p_profiler->cnProc); #endif @@ -593,9 +558,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, #endif // BN Processing -#ifdef NR_LDPC_PROFILER_DETAIL - start_meas(&p_profiler->bnProcPc); -#endif + NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->bnProcPc)); #ifndef UNROLL_BN_PROC_PC nrLDPC_bnProcPc(p_lut, bnProcBuf, bnProcBufRes, llrProcBuf, llrRes, Z); @@ -639,17 +602,13 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, } } #endif -#ifdef NR_LDPC_PROFILER_DETAIL - stop_meas(&p_profiler->bnProcPc); -#endif + NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->bnProcPc)); #ifdef NR_LDPC_DEBUG_MODE nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_LLR_RES, llrRes); #endif -#ifdef NR_LDPC_PROFILER_DETAIL - start_meas(&p_profiler->bnProc); -#endif + NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->bnProc)); #ifndef UNROLL_BN_PROC nrLDPC_bnProc(p_lut, bnProcBuf, bnProcBufRes, llrRes, Z); #else @@ -717,25 +676,19 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, } #endif - - -#ifdef NR_LDPC_PROFILER_DETAIL - stop_meas(&p_profiler->bnProc); -#endif + NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->bnProc)); #ifdef NR_LDPC_DEBUG_MODE nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_BN_PROC_RES, bnProcBufRes); #endif // BN results to CN processing buffer -#ifdef NR_LDPC_PROFILER_DETAIL - start_meas(&p_profiler->bn2cnProcBuf); -#endif - if (BG == 1) nrLDPC_bn2cnProcBuf_BG1(p_lut, bnProcBufRes, cnProcBuf, Z); - else nrLDPC_bn2cnProcBuf_BG2(p_lut, bnProcBufRes, cnProcBuf, Z); -#ifdef NR_LDPC_PROFILER_DETAIL - stop_meas(&p_profiler->bn2cnProcBuf); -#endif + NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->bn2cnProcBuf)); + if (BG == 1) + nrLDPC_bn2cnProcBuf_BG1(p_lut, bnProcBufRes, cnProcBuf, Z); + else + nrLDPC_bn2cnProcBuf_BG2(p_lut, bnProcBufRes, cnProcBuf, Z); + NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->bn2cnProcBuf)); #ifdef NR_LDPC_DEBUG_MODE nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC, cnProcBuf); @@ -743,40 +696,46 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, // Parity Check #ifdef NR_LDPC_ENABLE_PARITY_CHECK -#ifdef NR_LDPC_PROFILER_DETAIL - start_meas(&p_profiler->cnProcPc); + NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->cnProcPc)); + if (BG == 1) + pcRes = nrLDPC_cnProcPc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z); + else + pcRes = nrLDPC_cnProcPc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z); + NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->cnProcPc)); +#else + if (numIter > 2) { + int8_t llrOut[NR_LDPC_MAX_NUM_LLR] __attribute__((aligned(64))) = {0}; + int8_t* p_llrOut = outMode == nrLDPC_outMode_LLRINT8 ? p_out : llrOut; + nrLDPC_llrRes2llrOut(p_lut, p_llrOut, llrRes, Z, BG); + if (outMode == nrLDPC_outMode_BIT) + nrLDPC_llr2bitPacked(p_out, p_llrOut, numLLR); + else // if (outMode == nrLDPC_outMode_BITINT8) + nrLDPC_llr2bit(p_out, p_llrOut, numLLR); + if (check_crc((uint8_t*)p_out, p_decParams->block_length, p_decParams->crc_type)) { + LOG_D(PHY, "Segment CRC OK, exiting LDPC decoder\n"); + break; + } + } #endif - if (BG == 1) pcRes = nrLDPC_cnProcPc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z); - else pcRes = nrLDPC_cnProcPc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z); -#ifdef NR_LDPC_PROFILER_DETAIL - stop_meas(&p_profiler->cnProcPc); + } +#ifdef NR_LDPC_ENABLE_PARITY_CHECK + { + int8_t llrOut[NR_LDPC_MAX_NUM_LLR] __attribute__((aligned(64))) = {0}; + int8_t* p_llrOut = outMode == nrLDPC_outMode_LLRINT8 ? p_out : llrOut; + // Assign results from processing buffer to output + NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->llrRes2llrOut)); + nrLDPC_llrRes2llrOut(p_lut, p_llrOut, llrRes, Z, BG); + NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->llrRes2llrOut)); + // Hard-decision + NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->llr2bit)); + if (outMode == nrLDPC_outMode_BIT) + nrLDPC_llr2bitPacked(p_out, p_llrOut, numLLR); + else // if (outMode == nrLDPC_outMode_BITINT8) + nrLDPC_llr2bit(p_out, p_llrOut, numLLR); + NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->llr2bit)); + } #endif -#endif - } // end while - - // Last iteration - if (pcRes != 0) i++; - // Assign results from processing buffer to output -#ifdef NR_LDPC_PROFILER_DETAIL - start_meas(&p_profiler->llrRes2llrOut); -#endif - nrLDPC_llrRes2llrOut(p_lut, p_llrOut, llrRes, Z, BG); -#ifdef NR_LDPC_PROFILER_DETAIL - stop_meas(&p_profiler->llrRes2llrOut); -#endif - - // Hard-decision -#ifdef NR_LDPC_PROFILER_DETAIL - start_meas(&p_profiler->llr2bit); -#endif - if (outMode == nrLDPC_outMode_BIT) nrLDPC_llr2bitPacked(p_out, p_llrOut, numLLR); - else //if (outMode == nrLDPC_outMode_BITINT8) - nrLDPC_llr2bit(p_out, p_llrOut, numLLR); -#ifdef NR_LDPC_PROFILER_DETAIL - stop_meas(&p_profiler->llr2bit); -#endif - - return i; + return numIter; } diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h deleted file mode 100644 index 5678a7b3b7..0000000000 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h +++ /dev/null @@ -1,83 +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 - */ - -/*!\file nrLDPC_init_mem.h - * \brief Defines the function to initialize the LDPC decoder and sets correct LUTs. - * \author Sebastian Wagner (TCL Communications) Email: - * \date 07-12-2018 - * \version 1.0 - * \note - * \warning - */ - -#ifndef __NR_LDPC_INIT_MEM__H__ -#define __NR_LDPC_INIT_MEM__H__ - -#include -#include "nrLDPC_types.h" - -/** - \brief Allocates 32 byte aligned memory and initializes to zero - \param size Input size in bytes - \return Pointer to memory -*/ -static inline void* malloc32_clear(size_t size) -{ - void* ptr = (void*) memalign(64, size+64); - memset(ptr, 0, size); - return ptr; -} - -/** - \brief Allocates and initializes the internal decoder processing buffers - \param p_decParams Pointer to decoder parameters - \param p_lut Pointer to decoder LUTs - \return Number of LLR values -*/ -static inline t_nrLDPC_procBuf* nrLDPC_init_mem(void) -{ - t_nrLDPC_procBuf* p_procBuf = (t_nrLDPC_procBuf*) malloc32_clear(sizeof(t_nrLDPC_procBuf)); - - if (p_procBuf) - { - p_procBuf->cnProcBuf = (int8_t*) malloc32_clear(NR_LDPC_SIZE_CN_PROC_BUF*sizeof(int8_t)); - p_procBuf->cnProcBufRes = (int8_t*) malloc32_clear(NR_LDPC_SIZE_CN_PROC_BUF*sizeof(int8_t)); - p_procBuf->bnProcBuf = (int8_t*) malloc32_clear(NR_LDPC_SIZE_BN_PROC_BUF*sizeof(int8_t)); - p_procBuf->bnProcBufRes = (int8_t*) malloc32_clear(NR_LDPC_SIZE_BN_PROC_BUF*sizeof(int8_t)); - p_procBuf->llrRes = (int8_t*) malloc32_clear(NR_LDPC_MAX_NUM_LLR *sizeof(int8_t)); - p_procBuf->llrProcBuf = (int8_t*) malloc32_clear(NR_LDPC_MAX_NUM_LLR *sizeof(int8_t)); - } - - return(p_procBuf); -} - -static inline void nrLDPC_free_mem(t_nrLDPC_procBuf* p_procBuf) -{ - free(p_procBuf->cnProcBuf); - free(p_procBuf->cnProcBufRes); - free(p_procBuf->bnProcBuf); - free(p_procBuf->bnProcBufRes); - free(p_procBuf->llrRes); - free(p_procBuf->llrProcBuf); - - free(p_procBuf); -} -#endif diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h index 513bcb1732..04ec5822d8 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h @@ -88,6 +88,7 @@ typedef struct nrLDPC_dec_params { uint8_t numMaxIter; /**< Maximum number of iterations */ int block_length; e_nrLDPC_outMode outMode; /**< Output format */ + int crc_type; } t_nrLDPC_dec_params; /** diff --git a/openair1/PHY/CODING/nrLDPC_extern.h b/openair1/PHY/CODING/nrLDPC_extern.h index e4e4032681..5c24b5c3b5 100644 --- a/openair1/PHY/CODING/nrLDPC_extern.h +++ b/openair1/PHY/CODING/nrLDPC_extern.h @@ -28,10 +28,10 @@ nrLDPC_decoffloadfunc_t nrLDPC_decoder_offload; nrLDPC_dectopfunc_t top_testsuite; #else /* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */ -extern int load_nrLDPClib(char *version) ; -extern int load_nrLDPClib_offload(void) ; -extern int free_nrLDPClib_offload(void) ; -extern int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr); // for ldpctest +int load_nrLDPClib(char *version); +int load_nrLDPClib_offload(void); +int free_nrLDPClib_offload(void); +int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t *nrLDPC_encoder_ptr); // for ldpctest /* ldpc coder/decoder functions, as loaded by load_nrLDPClib(). */ extern nrLDPC_initcallfunc_t nrLDPC_initcall; diff --git a/openair1/PHY/CODING/nrLDPC_load.c b/openair1/PHY/CODING/nrLDPC_load.c index 400fb8d836..7de9276efa 100644 --- a/openair1/PHY/CODING/nrLDPC_load.c +++ b/openair1/PHY/CODING/nrLDPC_load.c @@ -49,26 +49,23 @@ static loader_shlibfunc_t shlib_fdesc[3]; char *arg[64]={"ldpctest",NULL}; int load_nrLDPClib(char *version) { - char *ptr = (char*)config_get_if(); - char libname[64]="ldpc"; + char *ptr = (char *)config_get_if(); + char libname[64] = "ldpc"; - if ( ptr==NULL ) {// phy simulators, config module possibly not loaded - load_configmodule(1,arg,CONFIG_ENABLECMDLINEONLY) ; - logInit(); - } - shlib_fdesc[0].fname = "nrLDPC_decod"; - shlib_fdesc[1].fname = "nrLDPC_encod"; - shlib_fdesc[2].fname = "nrLDPC_initcall"; - int ret; - if (version) - ret=load_module_version_shlib(libname,version,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL); - else - ret=load_module_shlib(libname,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL); - AssertFatal( (ret >= 0),"Error loading ldpc decoder"); - nrLDPC_decoder = (nrLDPC_decoderfunc_t)shlib_fdesc[0].fptr; - nrLDPC_encoder = (nrLDPC_encoderfunc_t)shlib_fdesc[1].fptr; - nrLDPC_initcall = (nrLDPC_initcallfunc_t)shlib_fdesc[2].fptr; -return 0; + if (ptr == NULL) { // phy simulators, config module possibly not loaded + load_configmodule(1, arg, CONFIG_ENABLECMDLINEONLY); + logInit(); + } + shlib_fdesc[0].fname = "nrLDPC_decod"; + shlib_fdesc[1].fname = "nrLDPC_encod"; + shlib_fdesc[2].fname = "nrLDPC_initcall"; + int ret; + ret = load_module_version_shlib(libname, version, shlib_fdesc, sizeofArray(shlib_fdesc), NULL); + AssertFatal((ret >= 0), "Error loading ldpc decoder"); + nrLDPC_decoder = (nrLDPC_decoderfunc_t)shlib_fdesc[0].fptr; + nrLDPC_encoder = (nrLDPC_encoderfunc_t)shlib_fdesc[1].fptr; + nrLDPC_initcall = (nrLDPC_initcallfunc_t)shlib_fdesc[2].fptr; + return 0; } int load_nrLDPClib_offload(void) { diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c index 03c7beb771..90ddbe656b 100644 --- a/openair1/PHY/CODING/nr_rate_matching.c +++ b/openair1/PHY/CODING/nr_rate_matching.c @@ -551,7 +551,8 @@ int nr_rate_matching_ldpc_rx(uint32_t Tbslbrm, printf("nr_rate_matching_ldpc_rx: Clear %d, E %u, k0 %u, Ncb %u, rvidx %d, Tbslbrm %u\n", clear, E, ind, Ncb, rvidx, Tbslbrm); #endif - if (clear==1) memset(w,0,Ncb*sizeof(int16_t)); + if (clear == 1) + memset(w, 0, Ncb * sizeof(int16_t)); k=0; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 0e48d807d8..acf7820f48 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -243,20 +243,8 @@ static void nr_processULSegment(void *arg) ////////////////////////////////// pl =====> llrProcBuf ////////////////////////////////// p_decoderParms->block_length = length_dec; - rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, (int8_t *)&pl[0], llrProcBuf, p_procTime, &ulsch_harq->abort_decode); - - if (rdata->decodeIterations == p_decoderParms->numMaxIter+1 ) { - // We have not decoded succesfully and we have not aborted - // We check the CRC, itf it is ok, let's assume the payload is correctly decoded - // (so the remaining errors are only in the redundancy (parity) bits) - if (check_crc((uint8_t *)llrProcBuf, length_dec, ulsch_harq->F, crc_type)) { - PRINT_CRC_CHECK(LOG_I(PHY,"Segment %d CRC OK, iterations %d/%d\n",r,rdata->decodeIterations,max_ldpc_iterations)); - rdata->decodeIterations = p_decoderParms->numMaxIter; - } else { - PRINT_CRC_CHECK(LOG_I(PHY,"CRC NOK\n")); - rdata->decodeIterations = max_ldpc_iterations + 1; - } - } + p_decoderParms->crc_type = crc_type; + rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, (int8_t *)pl, llrProcBuf, p_procTime, &ulsch_harq->abort_decode); if (rdata->decodeIterations <= p_decoderParms->numMaxIter) memcpy(ulsch_harq->c[r],llrProcBuf, Kr>>3); @@ -273,14 +261,20 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint8_t harq_pid, uint32_t G) { + if (!ulsch_llr) { + LOG_E(PHY, "ulsch_decoding.c: NULL ulsch_llr pointer\n"); + return -1; + } - NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id]; - NR_gNB_PUSCH *pusch = &phy_vars_gNB->pusch_vars[ULSCH_id]; - NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 1); - if (!harq_process) { - LOG_E(PHY,"ulsch_decoding.c: NULL harq_process pointer\n"); - return -1; + NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id]; + NR_gNB_PUSCH *pusch = &phy_vars_gNB->pusch_vars[ULSCH_id]; + NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process; + + if (!harq_process) { + LOG_E(PHY, "ulsch_decoding.c: NULL harq_process pointer\n"); + return -1; } uint8_t dtx_det = 0; @@ -296,12 +290,6 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint8_t n_layers = pusch_pdu->nrOfLayers; // ------------------------------------------------------------------ - if (!ulsch_llr) { - LOG_E(PHY,"ulsch_decoding.c: NULL ulsch_llr pointer\n"); - return -1; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,1); harq_process->TBS = pusch_pdu->pusch_data.tb_size; dtx_det = 0; @@ -493,13 +481,13 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, harq_process->c[r][m] = (uint8_t)llrProcBuf[m]; } - if (check_crc((uint8_t *)llrProcBuf, length_dec, harq_process->F, crc_type)) { + if (check_crc((uint8_t *)llrProcBuf, length_dec, crc_type)) { PRINT_CRC_CHECK(LOG_I(PHY, "Segment %d CRC OK\n", r)); decodeIterations = 2; } else { - PRINT_CRC_CHECK(LOG_I(PHY, "segment %d CRC NOK\n", r)); + PRINT_CRC_CHECK(LOG_I(PHY, "segment %d CRC NOK\n", r)); decodeIterations = ulsch->max_ldpc_iterations + 1; - } + } //} r_offset += E; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 5b3c726934..b9116a9f7d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -113,7 +113,7 @@ static bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, int A = dlsch->dlsch_config.TBS; int crc_length = A > 3824 ? 3 : 2; int crc_type = A > 3824 ? CRC24_A : CRC16; - if (!check_crc(b, A + crc_length*8, 0 /* F - unused */, crc_type)) { + if (!check_crc(b, A + crc_length * 8, crc_type)) { harq_process->ack = 0; dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations + 1; LOG_E(PHY, " Frame %d.%d LDPC global CRC fails, but individual LDPC CRC succeeded. %d segs\n", proc->frame_rx, proc->nr_slot_rx, harq_process->C); @@ -269,24 +269,11 @@ static void nr_processDLSegment(void *arg) //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN); p_decoderParms->block_length=length_dec; nrLDPC_initcall(p_decoderParms, (int8_t*)&pl[0], LDPCoutput); + p_decoderParms->crc_type = crc_type; rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, (int8_t *)&pl[0], LDPCoutput, &procTime, &harq_process->abort_decode); //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT); LOG_W(PHY,"rdata->decodeIterations = %d\n", rdata->decodeIterations); - if (rdata->decodeIterations < dlsch->max_ldpc_iterations + 2) { - // We have not aborted the decoding - if (check_crc((uint8_t *)LDPCoutput, length_dec, harq_process->F, crc_type)) { - LOG_D(PHY, "Segment %u CRC OK\n", r); - if (rdata->decodeIterations > dlsch->max_ldpc_iterations) { - LOG_W(PHY, "force ok\n"); - rdata->decodeIterations = dlsch->max_ldpc_iterations; - } - } else { - LOG_D(PHY, "%d.%d CRC NOT OK, iter %d\n", rdata->proc->frame_rx, rdata->proc->nr_slot_rx, rdata->decodeIterations); - rdata->decodeIterations = dlsch->max_ldpc_iterations + 1; - } - } else - LOG_D(PHY, "%d.%d another segment failure aborted this decode\n", rdata->proc->frame_rx, rdata->proc->nr_slot_rx); if (rdata->decodeIterations <= dlsch->max_ldpc_iterations) memcpy(harq_process->c[r], LDPCoutput, Kr >> 3); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index cb18f8f53b..dc0174c382 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -424,10 +424,8 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, */ } - - return ret; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT); + return ret; } diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 10953c9050..386c0cb004 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -680,7 +680,7 @@ int main(int argc, char **argv) c16_t **rxdata; rxdata = malloc(n_rx * sizeof(*rxdata)); for (int i = 0; i < n_rx; ++i) - rxdata[i] = calloc(gNB->frame_parms.samples_per_frame * sizeof(**rxdata),1); + rxdata[i] = calloc(gNB->frame_parms.samples_per_frame, sizeof(**rxdata)); NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]; @@ -1042,7 +1042,7 @@ int main(int argc, char **argv) pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = tbslbrm; pusch_pdu->pusch_data.rv_index = rv_index; pusch_pdu->pusch_data.harq_process_id = 0; - pusch_pdu->pusch_data.new_data_indicator = round == 0 ? 1 : 0; + pusch_pdu->pusch_data.new_data_indicator = round == 0 ? true : false; pusch_pdu->pusch_data.num_cb = 0; pusch_pdu->pusch_ptrs.ptrs_time_density = ptrs_time_density; pusch_pdu->pusch_ptrs.ptrs_freq_density = ptrs_freq_density;