diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ce715f0c7..214a16b79a 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/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c index f0f4769faf..5531a3aed3 100644 --- a/common/utils/threadPool/thread-pool.c +++ b/common/utils/threadPool/thread-pool.c @@ -218,14 +218,8 @@ int main() { tmp=pullNotifiedFIFO(&myFifo); printf("pulled: %lu\n", tmp->key); displayList(&myFifo); - abortNotifiedFIFOJob(&myFifo,1005); - printf("aborted 1005\n"); - displayList(&myFifo); pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 12345678, NULL, NULL)); displayList(&myFifo); - abortNotifiedFIFOJob(&myFifo,12345678); - printf("aborted 12345678\n"); - displayList(&myFifo); do { tmp=pollNotifiedFIFO(&myFifo); diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h index b06671c728..66e1152f48 100644 --- a/common/utils/threadPool/thread-pool.h +++ b/common/utils/threadPool/thread-pool.h @@ -197,31 +197,6 @@ static inline time_stats_t exec_time_stats_NotifiedFIFO(const notifiedFIFO_elt_t return ts; } -// 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 int abortNotifiedFIFOJob(notifiedFIFO_t *nf, uint64_t key) { - mutexlock(nf->lockF); - int nbDeleted=0; - notifiedFIFO_elt_t **start=&nf->outF; - - while(*start!=NULL) { - if ( (*start)->key == key ) { - notifiedFIFO_elt_t *request=*start; - *start=(*start)->next; - delNotifiedFIFO_elt(request); - nbDeleted++; - } else - start=&(*start)->next; - } - - if (nf->outF == NULL) - nf->inF=NULL; - - mutexunlock(nf->lockF); - return nbDeleted; -} - // This functions aborts all messages in the queue, and marks the queue as // "aborted", such that every call to it will return NULL static inline void abortNotifiedFIFO(notifiedFIFO_t *nf) { @@ -317,39 +292,6 @@ static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpo return msg; } -static inline int abortTpoolJob(tpool_t *t, uint64_t key) { - int nbRemoved=0; - notifiedFIFO_t *nf=&t->incomingFifo; - - mutexlock(nf->lockF); - notifiedFIFO_elt_t **start=&nf->outF; - - while(*start!=NULL) { - if ( (*start)->key == key ) { - notifiedFIFO_elt_t *request=*start; - *start=(*start)->next; - delNotifiedFIFO_elt(request); - nbRemoved++; - } else - start=&(*start)->next; - } - - if (t->incomingFifo.outF==NULL) - t->incomingFifo.inF=NULL; - - struct one_thread *thread = t->allthreads; - while (thread != NULL) { - if (thread->runningOnKey == key) { - thread->dropJob = true; - nbRemoved++; - } - - thread = thread->next; - } - - mutexunlock(nf->lockF); - return nbRemoved; -} static inline int abortTpool(tpool_t *t) { int nbRemoved=0; /* disables threading: if a message comes in now, we cannot have a race below diff --git a/common/utils/threadPool/thread-pool.md b/common/utils/threadPool/thread-pool.md index 249951666c..311857ff3e 100644 --- a/common/utils/threadPool/thread-pool.md +++ b/common/utils/threadPool/thread-pool.md @@ -2,8 +2,6 @@ The **thread pool** is a working server, made of a set of worker threads that can be mapped on CPU cores. Each thread pool has an **input queue** ("**FIFO**"), from which its workers pick **jobs** (FIFO element) to execute. When a job is done, the worker sends a message to an output queue, if it has been defined. -A selective abort allows to cancel parallel jobs. This can be useful, e.g., if a client pushed jobs, but from a response of one job, the other linked jobs become useless. - All the thread pool functions are thread safe. The functions executed by worker threads are provided by the thread pool client, so the client has to handle the concurrency/parallel execution of his functions. ## license @@ -56,7 +54,6 @@ Queues can be used to enqueue messages/jobs, of type `notifiedFIFO_t`. * `pushNotifiedFIFO()`: Add a job to a queue * `pullNotifiedFIFO()`: Pull a job from a queue. This call is blocking until a job arrived. * `pollNotifiedFIFO()`: Pull a job from a queue. This call is not blocking, so it returns always very shortly -* `abortNotifiedFIFOJob()`: Allows to delete all waiting jobs that match a key (see `key` in jobs definition) * `abortNotifiedFIFO()`: Aborts a FIFO, such that it will always return `NULL` Note that in 99.9% of cases, `pull()` is better than `poll()`. @@ -104,12 +101,6 @@ Like `pullNotifiedFIFO()`, but non-blocking: they check if the queue `nf` contai Note that unlike for `pullNotifiedFIFO()`, returning `NULL` does not inform whether the queue has been aborted; the caller should manually check the `abortFIFO` flag of `nf` in this case. -### `int abortNotifiedFIFOJob(notifiedFIFO_t *nf, uint64_t key)` - -Aborts all jobs in FIFO queue `nf` with key `key`. Jobs already under execution will be silently dropped and not put in the FIFO return queue, if any. - -Returns the number of aborted jobs. - ### `void abortNotifiedFIFO(notifiedFIFO_t *nf)` Aborts the entire FIFO queue `nf`: all jobs will be dropped, and the FIFO is marked as aborted, such that a call to `pullNotifiedFIFO()` returns `NULL`. @@ -135,10 +126,6 @@ If they need a return value (e.g., result of a computation), they have to create ## Abort -A abort service `abortTpoolJob()` allows to abort all jobs that match a key (see a job's `key`). When the abort returns, it garanties that no job (matching the key) response will be posted on response queues. - -Nevertheless, jobs already performed before the return of `abortTpoolJob()` are pushed in the response Fifo queue. - `abortTpool()` kills all jobs in the Tpool, and terminates the pool. ## API details @@ -171,7 +158,7 @@ Adds a job for processing in the thread pool. The job data you can set are, inside `msg`: -* `key`: an arbitrary key to find a job in a response queue, and which can be used to abort jobs using `abortTpoolJob()`. +* `key`: an arbitrary key to find a job in a response queue. * `reponseFifo`: if non-`NULL`, the message will be sent back on this queue when the job is done. If `NULL`, the thread pool automatically frees the job when it is done. * `processingFunc`: the function to execute for this job. @@ -187,14 +174,6 @@ Multiple return queues might be useful. Consider the following example in the eN The same as `pullTpool()` in a non-blocking fashion (an alternative name would have been `pollTpool()`). -### `int abortTpoolJob(tpool_t *t, uint64_t key)` - -Is a facility to cancel work you pushed to a thread pool: every job with a given `key` will be deleted, and results of jobs with such `key` under execution will be dropped. - -It returns the number of aborted jobs, including the ones that are currently being executed. - -I used it once: when eNB performs turbo decode, I push all segments in the thread pool. But when I get back the decoding results, if one segment can't be decoded, I don't need the results of the other segments of the same UE. - ### `int abortTpool(tpool_t *t)` Aborts the complete Tpool: cancel every work in the input queue, marks to drop existing jobs in processing, and terminates all worker threads. It is afterwards still possible to call functions such as `pushTpool()`, but each calling thread will execute the job itself. diff --git a/docker/Dockerfile.gNB.aw2s.rhel9 b/docker/Dockerfile.gNB.aw2s.rhel9 index 7e5ea8fe25..6985ab2108 100644 --- a/docker/Dockerfile.gNB.aw2s.rhel9 +++ b/docker/Dockerfile.gNB.aw2s.rhel9 @@ -67,10 +67,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libcoding.so \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /usr/local/lib/ diff --git a/docker/Dockerfile.gNB.aw2s.rocky b/docker/Dockerfile.gNB.aw2s.rocky index 8d368d1000..26eabc535f 100644 --- a/docker/Dockerfile.gNB.aw2s.rocky +++ b/docker/Dockerfile.gNB.aw2s.rocky @@ -68,10 +68,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libcoding.so \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /usr/local/lib/libori.so \ /usr/local/lib/ @@ -86,19 +83,7 @@ COPY --from=gnb-base \ RUN ln -s /usr/local/lib/libaw2sori_transpro.so /usr/local/lib/libthirdparty_transpro.so && \ ln -s /usr/local/lib/liboai_eth_transpro.so /usr/local/lib/liboai_transpro.so && \ - ldconfig && \ - echo "ldd on nr-softmodem" && ldd /opt/oai-gnb-aw2s/bin/nr-softmodem && \ - echo "ldd on liboai_eth_transpro" && ldd /usr/local/lib/liboai_eth_transpro.so && \ - echo "ldd on librfsimulator" && ldd /usr/local/lib/librfsimulator.so && \ - echo "ldd on libaw2sori_transpro" && ldd /usr/local/lib/libaw2sori_transpro.so && \ - echo "ldd on libcoding" && ldd /usr/local/lib/libcoding.so && \ - echo "ldd on libparams_libconfig" && ldd /usr/local/lib/libparams_libconfig.so && \ - echo "ldd on libdfts" && ldd /usr/local/lib/libdfts.so && \ - echo "ldd on libldpc" && ldd /usr/local/lib/libldpc.so && \ - echo "ldd on libldpc_optim" && ldd /usr/local/lib/libldpc_optim.so && \ - echo "ldd on libldpc_optim8seg" && ldd /usr/local/lib/libldpc_optim8seg.so && \ - echo "ldd on libldpc_orig" && ldd /usr/local/lib/libldpc_orig.so && \ - echo "ldd on libtelnetsrv" && ldd /usr/local/lib/libtelnetsrv.so + ldconfig WORKDIR /opt/oai-gnb-aw2s ENTRYPOINT ["/opt/oai-gnb-aw2s/bin/entrypoint.sh"] diff --git a/docker/Dockerfile.gNB.aw2s.ubuntu20 b/docker/Dockerfile.gNB.aw2s.ubuntu20 index a38cb34d78..642076163b 100644 --- a/docker/Dockerfile.gNB.aw2s.ubuntu20 +++ b/docker/Dockerfile.gNB.aw2s.ubuntu20 @@ -70,10 +70,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libcoding.so \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /usr/local/lib/ diff --git a/docker/Dockerfile.gNB.rhel9 b/docker/Dockerfile.gNB.rhel9 index d3ef5d9b64..74916d7888 100644 --- a/docker/Dockerfile.gNB.rhel9 +++ b/docker/Dockerfile.gNB.rhel9 @@ -64,10 +64,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libcoding.so \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \ /usr/local/lib/ diff --git a/docker/Dockerfile.gNB.rocky b/docker/Dockerfile.gNB.rocky index bef0094023..d6e225aa73 100644 --- a/docker/Dockerfile.gNB.rocky +++ b/docker/Dockerfile.gNB.rocky @@ -68,10 +68,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libcoding.so \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \ /usr/local/lib/ @@ -107,21 +104,8 @@ WORKDIR /usr/local/share/uhd/rfnoc COPY --from=gnb-base /usr/local/share/uhd/rfnoc/ . RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ - ldconfig && \ - echo "ldd on nr-softmodem" && ldd /opt/oai-gnb/bin/nr-softmodem && \ - echo "ldd on liboai_eth_transpro" && ldd /usr/local/lib/liboai_eth_transpro.so && \ - echo "ldd on librfsimulator" && ldd /usr/local/lib/librfsimulator.so && \ - echo "ldd on liboai_usrpdevif" && ldd /usr/local/lib/liboai_usrpdevif.so && \ - echo "ldd on libcoding" && ldd /usr/local/lib/libcoding.so && \ - echo "ldd on libparams_libconfig" && ldd /usr/local/lib/libparams_libconfig.so && \ - echo "ldd on libdfts" && ldd /usr/local/lib/libdfts.so && \ - echo "ldd on libldpc" && ldd /usr/local/lib/libldpc.so && \ - echo "ldd on libldpc_optim" && ldd /usr/local/lib/libldpc_optim.so && \ - echo "ldd on libldpc_optim8seg" && ldd /usr/local/lib/libldpc_optim8seg.so && \ - echo "ldd on libldpc_orig" && ldd /usr/local/lib/libldpc_orig.so && \ - echo "ldd on libtelnetsrv" && ldd /usr/local/lib/libtelnetsrv.so && \ - echo "ldd on libtelnetsrv_ci" && ldd /usr/local/lib/libtelnetsrv_ci.so - + ldconfig + # Copy the relevant configuration files for gNB WORKDIR /opt/oai-gnb/etc COPY --from=gnb-build /oai-ran/docker/etc . diff --git a/docker/Dockerfile.gNB.ubuntu20 b/docker/Dockerfile.gNB.ubuntu20 index fe2d65dc85..f9ee719839 100644 --- a/docker/Dockerfile.gNB.ubuntu20 +++ b/docker/Dockerfile.gNB.ubuntu20 @@ -70,10 +70,7 @@ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libcoding.so \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \ /usr/local/lib/ diff --git a/docker/Dockerfile.nrUE.rhel9 b/docker/Dockerfile.nrUE.rhel9 index 654eeef861..53b179a935 100644 --- a/docker/Dockerfile.nrUE.rhel9 +++ b/docker/Dockerfile.nrUE.rhel9 @@ -70,10 +70,7 @@ COPY --from=nr-ue-build \ /oai-ran/cmake_targets/ran_build/build/libcoding.so \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_5Gue.so \ /usr/local/lib/ diff --git a/docker/Dockerfile.nrUE.rocky b/docker/Dockerfile.nrUE.rocky index 072d7e5445..f0cc4b5788 100644 --- a/docker/Dockerfile.nrUE.rocky +++ b/docker/Dockerfile.nrUE.rocky @@ -75,10 +75,7 @@ COPY --from=nr-ue-build \ /oai-ran/cmake_targets/ran_build/build/libcoding.so \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_5Gue.so \ /usr/local/lib/ @@ -114,21 +111,8 @@ WORKDIR /usr/local/share/uhd/rfnoc COPY --from=nr-ue-base /usr/local/share/uhd/rfnoc/ . RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \ - ldconfig && \ - echo "ldd on nr-uesoftmodem" && ldd /opt/oai-nr-ue/bin/nr-uesoftmodem && \ - echo "ldd on liboai_eth_transpro" && ldd /usr/local/lib/liboai_eth_transpro.so && \ - echo "ldd on librfsimulator" && ldd /usr/local/lib/librfsimulator.so && \ - echo "ldd on liboai_usrpdevif" && ldd /usr/local/lib/liboai_usrpdevif.so && \ - echo "ldd on libcoding" && ldd /usr/local/lib/libcoding.so && \ - echo "ldd on libparams_libconfig" && ldd /usr/local/lib/libparams_libconfig.so && \ - echo "ldd on libdfts" && ldd /usr/local/lib/libdfts.so && \ - echo "ldd on libldpc" && ldd /usr/local/lib/libldpc.so && \ - echo "ldd on libldpc_optim" && ldd /usr/local/lib/libldpc_optim.so && \ - echo "ldd on libldpc_optim8seg" && ldd /usr/local/lib/libldpc_optim8seg.so && \ - echo "ldd on libldpc_orig" && ldd /usr/local/lib/libldpc_orig.so && \ - echo "ldd on libtelnetsrv" && ldd /usr/local/lib/libtelnetsrv.so && \ - echo "ldd on libtelnetsrv_5Gue" && ldd /usr/local/lib/libtelnetsrv_5Gue.so - + ldconfig + # Copy the relevant configuration files for eNB WORKDIR /opt/oai-nr-ue/etc COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/ue.* . diff --git a/docker/Dockerfile.nrUE.ubuntu20 b/docker/Dockerfile.nrUE.ubuntu20 index 0eb22c818f..c298394abd 100644 --- a/docker/Dockerfile.nrUE.ubuntu20 +++ b/docker/Dockerfile.nrUE.ubuntu20 @@ -76,10 +76,7 @@ COPY --from=nr-ue-build \ /oai-ran/cmake_targets/ran_build/build/libcoding.so \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_5Gue.so \ /usr/local/lib/ diff --git a/docker/Dockerfile.phySim.rhel9 b/docker/Dockerfile.phySim.rhel9 index 69d19bc5aa..145c3b3c2c 100644 --- a/docker/Dockerfile.phySim.rhel9 +++ b/docker/Dockerfile.phySim.rhel9 @@ -89,8 +89,7 @@ COPY --from=phy-sim-build \ /usr/lib64/libasan.so.6 \ /usr/lib64/libubsan.so.1 \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc.so \ - /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \ + /oai-ran/cmake_targets/ran_build/build/libldpc*.so \ /usr/local/lib/ RUN ldconfig diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c index 896e69a4b1..110a659000 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c @@ -982,7 +982,9 @@ uint8_t phy_threegpplte_turbo_decoder16(int16_t *y, time_stats_t *gamma_stats, time_stats_t *ext_stats, time_stats_t *intl1_stats, - time_stats_t *intl2_stats) { + time_stats_t *intl2_stats, + decode_abort_t *ab) +{ /* y is a pointer to the input decoded_bytes is a pointer to the decoded output n is the size in bits of the coded block, with the tail */ @@ -1356,7 +1358,8 @@ uint8_t phy_threegpplte_turbo_decoder16(int16_t *y, return(iteration_cnt); } } - + if (check_abort(ab)) + return max_iterations + 2; // do log_map from first parity bit if (iteration_cnt < max_iterations) { log_map16(systematic1,yparity1,m11,m10,alpha,beta,ext,n,0,F,offset8_flag,alpha_stats,beta_stats,gamma_stats,ext_stats); @@ -1390,9 +1393,7 @@ uint8_t phy_threegpplte_turbo_decoder16(int16_t *y, _mm_empty(); _m_empty(); #endif + if (iteration_cnt > max_iterations) + set_abort(ab, true); return(iteration_cnt); } - - - - diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c index 0614a9d071..1c18f909a7 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c @@ -792,7 +792,9 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, time_stats_t *gamma_stats, time_stats_t *ext_stats, time_stats_t *intl1_stats, - time_stats_t *intl2_stats) { + time_stats_t *intl2_stats, + decode_abort_t *ab) +{ /* y is a pointer to the input decoded_bytes is a pointer to the decoded output n is the size in bits of the coded block, with the tail */ @@ -1278,7 +1280,8 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, return(iteration_cnt); } } - + if (check_abort(ab)) + return max_iterations + 2; // do a new iteration if it is not yet decoded if (iteration_cnt < max_iterations) { log_map8(systematic1,yparity1,m11,m10,alpha,beta,ext,n2,0,F,offset8_flag,alpha_stats,beta_stats,gamma_stats,ext_stats); @@ -1303,6 +1306,7 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, } } } - + if (iteration_cnt > max_iterations) + set_abort(ab, true); return(iteration_cnt); } diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index 66cd8ffde7..f4064fe844 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -185,7 +185,6 @@ int test_ldpc(short max_iterations, } } - //determine number of bits in codeword if (block_length>3840) { @@ -270,6 +269,8 @@ int test_ldpc(short max_iterations, if (ntrials==0) encoder_orig(test_input,channel_input, Zc, BG, block_length, BG, &impp); impp.gen_code=0; + decode_abort_t dec_abort; + init_abort(&dec_abort); for (int trial=0; trial < ntrials; trial++) { segment_bler = 0; @@ -359,7 +360,12 @@ int test_ldpc(short max_iterations, } for(int j=0;j 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; @@ -529,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/coding_load.c b/openair1/PHY/CODING/coding_load.c index 28c5c154d1..0b9e524690 100644 --- a/openair1/PHY/CODING/coding_load.c +++ b/openair1/PHY/CODING/coding_load.c @@ -58,21 +58,22 @@ decoder_if_t *decoder8; encoder_if_t *encoder; extern int _may_i_use_cpu_feature(unsigned __int64); -uint8_t nodecod(int16_t *y, - int16_t *y2, - uint8_t *decoded_bytes, - uint8_t *decoded_bytes2, - uint16_t n, - uint8_t max_iterations, - uint8_t crc_type, - uint8_t F, - time_stats_t *init_stats, - time_stats_t *alpha_stats, - time_stats_t *beta_stats, - time_stats_t *gamma_stats, - time_stats_t *ext_stats, - time_stats_t *intl1_stats, - time_stats_t *intl2_stats) +uint8_t nodecod(int16_t *y, + int16_t *y2, + uint8_t *decoded_bytes, + uint8_t *decoded_bytes2, + uint16_t n, + uint8_t max_iterations, + uint8_t crc_type, + uint8_t F, + time_stats_t *init_stats, + time_stats_t *alpha_stats, + time_stats_t *beta_stats, + time_stats_t *gamma_stats, + time_stats_t *ext_stats, + time_stats_t *intl1_stats, + time_stats_t *intl2_stats, + decode_abort_t *ab) { return max_iterations+1; }; 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) { + LOG_D(PHY, "set abort: %d, %d\n", numIter, p_decParams->numMaxIter); + set_abort(ab, true); + } return numIter; } @@ -147,7 +155,13 @@ int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_ \param p_decParamsnrLDPC decoder parameters \param p_profilernrLDPC profiler statistics */ -static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_time_stats* p_profiler) +static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, + int8_t* p_out, + uint32_t numLLR, + t_nrLDPC_lut* p_lut, + t_nrLDPC_dec_params* p_decParams, + t_nrLDPC_time_stats* p_profiler, + decode_abort_t* ab) { uint16_t Z = p_decParams->Z; uint8_t BG = p_decParams->BG; @@ -162,48 +176,26 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_ 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); @@ -213,12 +205,10 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_ // 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) { @@ -290,23 +280,19 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_ } #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); @@ -314,10 +300,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_ #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); @@ -362,18 +345,14 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_ } #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 @@ -474,12 +453,16 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_ // estimated after only one iteration // First iteration finished - - while ( (i < numMaxIter) && (pcRes != 0) ) { - // Increase iteration counter - i++; - - // 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 @@ -575,9 +558,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_ #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); @@ -621,17 +602,13 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_ } } #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 @@ -699,25 +676,19 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_ } #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); @@ -725,40 +696,46 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_ // 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_decoder_CL.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_CL.c index c60286ab3a..74b3dbb41b 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_CL.c +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_CL.c @@ -334,8 +334,12 @@ void nrLDPC_initcall(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_ // init_LLR_DMA(p_decParams, p_llr, p_out); } - -int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out,t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats *time_decoder) +int32_t nrLDPC_decod(t_nrLDPC_dec_params *p_decParams, + int8_t *p_llr, + int8_t *p_out, + t_nrLDPC_procBuf *p_procBuf, + t_nrLDPC_time_stats *time_decoder, + decode_abort_t *ab) { uint16_t Zc = p_decParams->Z; uint8_t BG = p_decParams->BG; 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_defs.h b/openair1/PHY/CODING/nrLDPC_defs.h index 1aab887640..57d84bf8cb 100644 --- a/openair1/PHY/CODING/nrLDPC_defs.h +++ b/openair1/PHY/CODING/nrLDPC_defs.h @@ -73,7 +73,7 @@ typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,sho \param p_profiler LDPC profiler statistics */ -typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params* , int8_t*, int8_t* , t_nrLDPC_time_stats* ); +typedef int32_t (*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params *, int8_t *, int8_t *, t_nrLDPC_time_stats *, decode_abort_t *ab); typedef int32_t(*nrLDPC_decoffloadfunc_t)(t_nrLDPC_dec_params* , uint8_t, uint8_t, uint8_t , uint8_t, uint16_t, uint32_t, uint8_t, int8_t*, int8_t* ,uint8_t); typedef int32_t(*nrLDPC_dectopfunc_t)(void); 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/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index c72dd8cad1..1fb9ca985f 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -573,18 +573,10 @@ void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PR harq_list[j][i].c = malloc16(a_segments*sizeof(uint8_t *)); harq_list[j][i].d = malloc16(a_segments*sizeof(int16_t *)); const int sz=5*8448*sizeof(int16_t); + init_abort(&harq_list[j][i].abort_decode); for (int r=0; rharq_processes[i]) { memset(ulsch->harq_processes[i],0,sizeof(LTE_UL_eNB_HARQ_t)); + init_abort(&ulsch->harq_processes[i]->abort_decode); ulsch->harq_processes[i]->decodedBytes = (uint8_t *)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling); if (ulsch->harq_processes[i]->decodedBytes) @@ -281,11 +282,21 @@ void processULSegment(void * arg) { &eNB->ulsch_tc_gamma_stats, &eNB->ulsch_tc_ext_stats, &eNB->ulsch_tc_intl1_stats, - &eNB->ulsch_tc_intl2_stats); + &eNB->ulsch_tc_intl2_stats, + &ulsch_harq->abort_decode); } -int ulsch_decoding_data(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, - int UE_id,int harq_pid,int llr8_flag) { +/*! + \brief Decoding of ULSCH data component from 36-212. This one is single thread. + @param phy_vars_eNB Pointer to eNB top-level descriptor + @param UE_id ID of UE transmitting this PUSCH + @param harq_pid HARQ process ID + @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used + @returns 0 on success +*/ + +static int ulsch_decoding_data(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int UE_id, int harq_pid, int llr8_flag) +{ unsigned int r_offset=0; int offset = 0; LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; @@ -297,7 +308,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, decoder_if_t * td=llr8_flag == 0 ? *decoder16 : *decoder8; ulsch_harq->processedSegments=0; - + set_abort(&ulsch_harq->abort_decode, false); for (int r=0; rC; r++) { // printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]); // Get Turbo interleaver parameters diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c index 129dcef447..a89588050f 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c @@ -106,9 +106,10 @@ LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_ for (i=0; iharq_processes[i] = (LTE_DL_UE_HARQ_t *)malloc16(sizeof(LTE_DL_UE_HARQ_t)); - if (dlsch->harq_processes[i]) { memset(dlsch->harq_processes[i],0,sizeof(LTE_DL_UE_HARQ_t)); + init_abort(&dlsch->harq_processes[i]->abort_decode); + dlsch->harq_processes[i]->first_tx=1; dlsch->harq_processes[i]->b = (uint8_t *)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling); @@ -277,7 +278,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, printf("Segmentation: C %d, Cminus %d, Kminus %d, Kplus %d\n",harq_process->C,harq_process->Cminus,harq_process->Kminus,harq_process->Kplus); #endif opp_enabled=1; - + set_abort(&harq_process->abort_decode, false); for (r=0; rC; r++) { // Get Turbo interleaver parameters if (rCminus) @@ -381,7 +382,8 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, &phy_vars_ue->dlsch_tc_gamma_stats, &phy_vars_ue->dlsch_tc_ext_stats, &phy_vars_ue->dlsch_tc_intl1_stats, - &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); + &phy_vars_ue->dlsch_tc_intl2_stats, + &harq_process->abort_decode); //(is_crnti==0)?harq_pid:harq_pid+1); stop_UE_TIMING(phy_vars_ue->dlsch_turbo_decoding_stats); } diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h index 5f8763414e..a10e0515a5 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h +++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h @@ -269,6 +269,7 @@ typedef struct { uint32_t errors[8]; /// codeword this transport block is mapped to uint8_t codeword; + decode_abort_t abort_decode; } LTE_DL_UE_HARQ_t; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index f2028e6591..ec7f6cae69 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -49,16 +49,15 @@ NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL); @param is_crnti */ -uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, - uint8_t UE_id, - short *ulsch_llr, - NR_DL_FRAME_PARMS *frame_parms, - nfapi_nr_pusch_pdu_t *pusch_pdu, - uint32_t frame, - uint8_t nr_tti_rx, - uint8_t harq_pid, - uint32_t G); - +int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, + uint8_t UE_id, + short *ulsch_llr, + NR_DL_FRAME_PARMS *frame_parms, + nfapi_nr_pusch_pdu_t *pusch_pdu, + uint32_t frame, + uint8_t nr_tti_rx, + uint8_t harq_pid, + uint32_t G); /*! \brief Perform PUSCH unscrambling. TS 38.211 V15.4.0 subclause 6.3.1.1 @param llr, Pointer to llr bits @@ -70,17 +69,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, void nr_ulsch_unscrambling(int16_t* llr, uint32_t size, uint32_t Nid, uint32_t n_RNTI); -void nr_ulsch_layer_demapping(int16_t *llr_cw, - uint8_t Nl, - uint8_t mod_order, - uint32_t length, - int16_t **llr_layers); - -void nr_ulsch_procedures(PHY_VARS_gNB *gNB, - int frame_rx, - int slot_rx, - int UE_id, - uint8_t harq_pid); +void nr_ulsch_layer_demapping(int16_t *llr_cw, uint8_t Nl, uint8_t mod_order, uint32_t length, int16_t **llr_layers); NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index bcd73c58a9..ab63282c9b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -51,7 +51,12 @@ //#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 +//#define DEBUG_CRC +#ifdef DEBUG_CRC +#define PRINT_CRC_CHECK(a) a +#else +#define PRINT_CRC_CHECK(a) +#endif //extern double cpuf; @@ -100,6 +105,7 @@ NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL) ulsch.active = false; NR_UL_gNB_HARQ_t *harq = malloc16_clear(sizeof(*harq)); + init_abort(&harq->abort_decode); ulsch.harq_process = harq; harq->b = malloc16_clear(ulsch_bytes * sizeof(*harq->b)); harq->c = malloc16_clear(a_segments * sizeof(*harq->c)); @@ -113,185 +119,168 @@ NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL) return(ulsch); } -#ifdef PRINT_CRC_CHECK - static uint32_t prnt_crc_cnt = 0; -#endif - - void nr_processULSegment(void *arg) - { - ldpcDecode_t *rdata = (ldpcDecode_t *)arg; - PHY_VARS_gNB *phy_vars_gNB = rdata->gNB; - NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq; - t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms; - int length_dec; - int no_iteration_ldpc; - int Kr; - int Kr_bytes; - int K_bits_F; - uint8_t crc_type; - int i; - int j; - int r = rdata->segment_r; - int A = rdata->A; - int E = rdata->E; - int Qm = rdata->Qm; - int rv_index = rdata->rv_index; - int r_offset = rdata->r_offset; - uint8_t kc = rdata->Kc; - short *ulsch_llr = rdata->ulsch_llr; - int max_ldpc_iterations = p_decoderParms->numMaxIter; - int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__((aligned(32))); - - int16_t z[68 * 384 + 16] __attribute__((aligned(16))); - int8_t l[68 * 384 + 16] __attribute__((aligned(16))); - - __m128i *pv = (__m128i *)&z; - __m128i *pl = (__m128i *)&l; - - Kr = ulsch_harq->K; - Kr_bytes = Kr >> 3; - K_bits_F = Kr - ulsch_harq->F; - - t_nrLDPC_time_stats procTime = {0}; - t_nrLDPC_time_stats *p_procTime = &procTime; - - // start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats); - - //////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////// nr_deinterleaving_ldpc /////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////// ulsch_llr =====> ulsch_harq->e ////////////////////////////// - - /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) - int16_t harq_e[E]; - - nr_deinterleaving_ldpc(E, Qm, harq_e, ulsch_llr + r_offset); - - // for (int i =0; i<16; i++) - // printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,ulsch_harq->w[r][i], r_offset); - - stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats); - - ////////////////////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////// nr_rate_matching_ldpc_rx //////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////// - - ///////////////////////// ulsch_harq->e =====> ulsch_harq->d ///////////////////////// - - // start_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats); - - if (nr_rate_matching_ldpc_rx(rdata->tbslbrm, - p_decoderParms->BG, - p_decoderParms->Z, - ulsch_harq->d[r], - harq_e, - ulsch_harq->C, - rv_index, - ulsch_harq->d_to_be_cleared[r], - E, - ulsch_harq->F, - Kr - ulsch_harq->F - 2 * (p_decoderParms->Z)) - == -1) { - stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats); - - LOG_E(PHY, "ulsch_decoding.c: Problem in rate_matching\n"); - rdata->decodeIterations = max_ldpc_iterations + 1; - return; - } else { - stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats); - } - - ulsch_harq->d_to_be_cleared[r] = false; - - memset(ulsch_harq->c[r], 0, Kr_bytes); - - if (ulsch_harq->C == 1) { - if (A > 3824) - crc_type = CRC24_A; - else - crc_type = CRC16; - - length_dec = ulsch_harq->B; - } else { - crc_type = CRC24_B; - length_dec = (ulsch_harq->B + 24 * ulsch_harq->C) / ulsch_harq->C; - } - - // start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats); - - // set first 2*Z_c bits to zeros - memset(&z[0], 0, 2 * ulsch_harq->Z * sizeof(int16_t)); - // set Filler bits - memset((&z[0] + K_bits_F), 127, ulsch_harq->F * sizeof(int16_t)); - // Move coded bits before filler bits - memcpy((&z[0] + 2 * ulsch_harq->Z), ulsch_harq->d[r], (K_bits_F - 2 * ulsch_harq->Z) * sizeof(int16_t)); - // skip filler bits - memcpy((&z[0] + Kr), ulsch_harq->d[r] + (Kr - 2 * ulsch_harq->Z), (kc * ulsch_harq->Z - Kr) * sizeof(int16_t)); - // Saturate coded bits before decoding into 8 bits values - for (i = 0, j = 0; j < ((kc * ulsch_harq->Z) >> 4) + 1; i += 2, j++) { - pl[j] = _mm_packs_epi16(pv[i], pv[i + 1]); - } - ////////////////////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////// nrLDPC_decoder ///////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////// pl =====> llrProcBuf ////////////////////////////////// - p_decoderParms->block_length = length_dec; - no_iteration_ldpc = nrLDPC_decoder(p_decoderParms, (int8_t *)&pl[0], llrProcBuf, p_procTime); - - if (check_crc((uint8_t *)llrProcBuf, length_dec, ulsch_harq->F, crc_type)) { -#ifdef PRINT_CRC_CHECK - LOG_I(PHY,"Segment %d CRC OK, iterations %d/%d\n",r,no_iteration_ldpc,max_ldpc_iterations); -#endif - rdata->decodeIterations = no_iteration_ldpc; - if (rdata->decodeIterations > p_decoderParms->numMaxIter) rdata->decodeIterations--; - } else { -#ifdef PRINT_CRC_CHECK - LOG_I(PHY,"CRC NOK\n"); -#endif - rdata->decodeIterations = max_ldpc_iterations + 1; - } - - for (int m=0; m < Kr>>3; m ++) { - ulsch_harq->c[r][m]= (uint8_t) llrProcBuf[m]; - } - - //stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats); - } - -uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, - uint8_t ULSCH_id, - short *ulsch_llr, - NR_DL_FRAME_PARMS *frame_parms, - nfapi_nr_pusch_pdu_t *pusch_pdu, - uint32_t frame, - uint8_t nr_tti_rx, - uint8_t harq_pid, - uint32_t G) +static void nr_processULSegment(void *arg) { -#ifdef PRINT_CRC_CHECK - prnt_crc_cnt++; -#endif + ldpcDecode_t *rdata = (ldpcDecode_t *)arg; + PHY_VARS_gNB *phy_vars_gNB = rdata->gNB; + NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq; + t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms; + int length_dec; + int Kr; + int Kr_bytes; + int K_bits_F; + uint8_t crc_type; + int i; + int j; + int r = rdata->segment_r; + int A = rdata->A; + int E = rdata->E; + int Qm = rdata->Qm; + int rv_index = rdata->rv_index; + int r_offset = rdata->r_offset; + uint8_t kc = rdata->Kc; + short *ulsch_llr = rdata->ulsch_llr; + int max_ldpc_iterations = p_decoderParms->numMaxIter; + int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__((aligned(32))); - 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; + int16_t z[68 * 384 + 16] __attribute__((aligned(16))); + int8_t l[68 * 384 + 16] __attribute__((aligned(16))); - if (!harq_process) { - LOG_E(PHY,"ulsch_decoding.c: NULL harq_process pointer\n"); - return 1; + __m128i *pv = (__m128i *)&z; + __m128i *pl = (__m128i *)&l; + + Kr = ulsch_harq->K; + Kr_bytes = Kr >> 3; + K_bits_F = Kr - ulsch_harq->F; + + t_nrLDPC_time_stats procTime = {0}; + t_nrLDPC_time_stats *p_procTime = &procTime; + + // start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats); + + //////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////// nr_deinterleaving_ldpc /////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////// + + //////////////////////////// ulsch_llr =====> ulsch_harq->e ////////////////////////////// + + /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) + int16_t harq_e[E]; + + nr_deinterleaving_ldpc(E, Qm, harq_e, ulsch_llr + r_offset); + + // for (int i =0; i<16; i++) + // printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,ulsch_harq->w[r][i], r_offset); + + stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats); + + ////////////////////////////////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////// nr_rate_matching_ldpc_rx //////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////// + + ///////////////////////// ulsch_harq->e =====> ulsch_harq->d ///////////////////////// + + // start_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats); + + if (nr_rate_matching_ldpc_rx(rdata->tbslbrm, + p_decoderParms->BG, + p_decoderParms->Z, + ulsch_harq->d[r], + harq_e, + ulsch_harq->C, + rv_index, + ulsch_harq->d_to_be_cleared[r], + E, + ulsch_harq->F, + Kr - ulsch_harq->F - 2 * (p_decoderParms->Z)) + == -1) { + stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats); + + LOG_E(PHY, "ulsch_decoding.c: Problem in rate_matching\n"); + rdata->decodeIterations = max_ldpc_iterations + 1; + return; + } else { + stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats); + } + + ulsch_harq->d_to_be_cleared[r] = false; + + memset(ulsch_harq->c[r], 0, Kr_bytes); + + if (ulsch_harq->C == 1) { + if (A > 3824) + crc_type = CRC24_A; + else + crc_type = CRC16; + + length_dec = ulsch_harq->B; + } else { + crc_type = CRC24_B; + length_dec = (ulsch_harq->B + 24 * ulsch_harq->C) / ulsch_harq->C; + } + + // start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats); + + // set first 2*Z_c bits to zeros + memset(&z[0], 0, 2 * ulsch_harq->Z * sizeof(int16_t)); + // set Filler bits + memset((&z[0] + K_bits_F), 127, ulsch_harq->F * sizeof(int16_t)); + // Move coded bits before filler bits + memcpy((&z[0] + 2 * ulsch_harq->Z), ulsch_harq->d[r], (K_bits_F - 2 * ulsch_harq->Z) * sizeof(int16_t)); + // skip filler bits + memcpy((&z[0] + Kr), ulsch_harq->d[r] + (Kr - 2 * ulsch_harq->Z), (kc * ulsch_harq->Z - Kr) * sizeof(int16_t)); + // Saturate coded bits before decoding into 8 bits values + for (i = 0, j = 0; j < ((kc * ulsch_harq->Z) >> 4) + 1; i += 2, j++) { + pl[j] = _mm_packs_epi16(pv[i], pv[i + 1]); + } + ////////////////////////////////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////// nrLDPC_decoder ///////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////// + + ////////////////////////////////// pl =====> llrProcBuf ////////////////////////////////// + p_decoderParms->block_length = length_dec; + 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); + //stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats); +} + +int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, + uint8_t ULSCH_id, + short *ulsch_llr, + NR_DL_FRAME_PARMS *frame_parms, + nfapi_nr_pusch_pdu_t *pusch_pdu, + uint32_t frame, + uint8_t nr_tti_rx, + uint8_t harq_pid, + uint32_t G) + { + 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); + + 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; int Kr; int Kr_bytes; - - phy_vars_gNB->nbDecode = 0; + harq_process->processedSegments = 0; // ------------------------------------------------------------------ @@ -301,12 +290,6 @@ uint32_t 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; @@ -383,7 +366,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, if (harq_process->C > a_segments) { LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments); - return 1; + return -1; } #ifdef DEBUG_ULSCH_DECODING printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); @@ -399,18 +382,11 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, Kr_bytes = Kr >> 3; uint32_t offset = 0; - - if (phy_vars_gNB->ldpc_offload_flag) { + if (phy_vars_gNB->ldpc_offload_flag && mcs > 9) { int8_t llrProcBuf[22 * 384]; // if (dtx_det==0) { int16_t z_ol[68 * 384]; int8_t l_ol[68 * 384]; - - int16_t z[68 * 384 + 16] __attribute__((aligned(16))); - int8_t l[68 * 384 + 16] __attribute__((aligned(16))); - - __m128i *pv = (__m128i *)&z; - __m128i *pl = (__m128i *)&l; int crc_type; int length_dec; @@ -425,7 +401,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, crc_type = CRC24_B; length_dec = (harq_process->B + 24 * harq_process->C) / harq_process->C; } - int no_iteration_ldpc = 2; + int decodeIterations = 2; for (int r = 0; r < harq_process->C; r++) { int E = nr_get_E(G, harq_process->C, Qm, n_layers, r); memset(harq_process->c[r], 0, Kr_bytes); @@ -434,7 +410,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, if ((dtx_det == 0) && (pusch_pdu->pusch_data.rv_index == 0)) { // if (dtx_det==0){ - if (mcs > 9) { memcpy((&z_ol[0]), ulsch_llr + r_offset, E * sizeof(short)); __m128i *pv_ol128 = (__m128i *)&z_ol; __m128i *pl_ol128 = (__m128i *)&l_ol; @@ -446,68 +421,19 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, if (ret < 0) { LOG_E(PHY, "ulsch_decoding.c: Problem in LDPC decoder offload\n"); - no_iteration_ldpc = ulsch->max_ldpc_iterations + 1; - return 1; + decodeIterations = ulsch->max_ldpc_iterations + 1; + return -1; } - } else { - int K_bits_F = Kr - harq_process->F; - - t_nrLDPC_time_stats procTime = {0}; - t_nrLDPC_time_stats *p_procTime = &procTime; - /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) - int16_t harq_e[E]; - - nr_deinterleaving_ldpc(E, Qm, harq_e, ulsch_llr + r_offset); - - if (nr_rate_matching_ldpc_rx(pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes, - decParams.BG, - decParams.Z, - harq_process->d[r], - harq_e, - harq_process->C, - pusch_pdu->pusch_data.rv_index, - harq_process->d_to_be_cleared[r], - E, - harq_process->F, - Kr - harq_process->F - 2 * (decParams.Z)) - == -1) { - LOG_E(PHY, "ulsch_decoding.c: Problem in rate_matching\n"); - no_iteration_ldpc = ulsch->max_ldpc_iterations + 1; - return 1; - } - - harq_process->d_to_be_cleared[r] = false; - - // set first 2*Z_c bits to zeros - memset(&z[0], 0, 2 * harq_process->Z * sizeof(int16_t)); - // set Filler bits - memset((&z[0] + K_bits_F), 127, harq_process->F * sizeof(int16_t)); - // Move coded bits before filler bits - memcpy((&z[0] + 2 * harq_process->Z), harq_process->d[r], (K_bits_F - 2 * harq_process->Z) * sizeof(int16_t)); - // skip filler bits - memcpy((&z[0] + Kr), harq_process->d[r] + (Kr - 2 * harq_process->Z), (kc * harq_process->Z - Kr) * sizeof(int16_t)); - // Saturate coded bits before decoding into 8 bits values - for (int i = 0, j = 0; j < ((kc * harq_process->Z) >> 4) + 1; i += 2, j++) { - pl[j] = _mm_packs_epi16(pv[i], pv[i + 1]); - } - - no_iteration_ldpc = nrLDPC_decoder(&decParams, (int8_t *)pl, llrProcBuf, p_procTime); - } - for (int m = 0; m < Kr >> 3; m++) { harq_process->c[r][m] = (uint8_t)llrProcBuf[m]; } - 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); -#endif - no_iteration_ldpc = 2; + 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 { -#ifdef PRINT_CRC_CHECK - LOG_I(PHY, "segment %d CRC NOK\n", r); -#endif - no_iteration_ldpc = ulsch->max_ldpc_iterations + 1; + PRINT_CRC_CHECK(LOG_I(PHY, "segment %d CRC NOK\n", r)); + decodeIterations = ulsch->max_ldpc_iterations + 1; } //} @@ -521,9 +447,9 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, */ } else { dtx_det = 0; - no_iteration_ldpc = ulsch->max_ldpc_iterations + 1; + decodeIterations = ulsch->max_ldpc_iterations + 1; } - bool decodeSuccess = (no_iteration_ldpc <= ulsch->max_ldpc_iterations); + bool decodeSuccess = (decodeIterations <= ulsch->max_ldpc_iterations); if (decodeSuccess) { memcpy(harq_process->b + offset, harq_process->c[r], Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); offset += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); @@ -556,16 +482,16 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, harq_process->round, harq_process->TBS); ulsch->handled = 1; - no_iteration_ldpc = ulsch->max_ldpc_iterations + 1; + decodeIterations = ulsch->max_ldpc_iterations + 1; LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id); nr_fill_indication(phy_vars_gNB, ulsch->frame, ulsch->slot, ULSCH_id, harq_pid, 1, 0); } - ulsch->last_iteration_cnt = no_iteration_ldpc; + ulsch->last_iteration_cnt = decodeIterations; } else { dtx_det = 0; - + set_abort(&harq_process->abort_decode, false); for (int r = 0; r < harq_process->C; r++) { int E = nr_get_E(G, harq_process->C, Qm, n_layers, r); union ldpcReqUnion id = {.s = {ulsch->rnti, frame, nr_tti_rx, 0, 0}}; @@ -591,12 +517,11 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, rdata->ulsch_id = ULSCH_id; rdata->tbslbrm = pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes; pushTpool(&phy_vars_gNB->threadPool, req); - phy_vars_gNB->nbDecode++; - LOG_D(PHY, "Added a block to decode, in pipe: %d\n", phy_vars_gNB->nbDecode); + LOG_D(PHY, "Added a block to decode, in pipe: %d\n", r); r_offset += E; offset += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); ////////////////////////////////////////////////////////////////////////////////////////// } } - return 1; + return harq_process->C; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 1c049acbc6..d3c7380a6c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -70,7 +70,15 @@ void nr_dlsch_unscrambling(int16_t *llr, uint32_t size, uint8_t q, uint32_t Nid, nr_codeword_unscrambling(llr, size, q, Nid, n_RNTI); } -bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool last, notifiedFIFO_t *nf_p, int b_size, uint8_t b[b_size], int *num_seg_ok, UE_nr_rxtx_proc_t *proc) { +static bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, + notifiedFIFO_elt_t *req, + notifiedFIFO_t *nf_p, + bool last, + int b_size, + uint8_t b[b_size], + int *num_seg_ok, + UE_nr_rxtx_proc_t *proc) +{ ldpcDecode_ue_t *rdata = (ldpcDecode_ue_t*) NotifiedFifoData(req); NR_DL_UE_HARQ_t *harq_process = rdata->harq_process; NR_UE_DLSCH_t *dlsch = (NR_UE_DLSCH_t *) rdata->dlsch; @@ -89,13 +97,7 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool (*num_seg_ok)++; } else { - if ( !last ) { - int nb=abortTpoolJob(&get_nrUE_params()->Tpool, req->key); - nb+=abortNotifiedFIFOJob(nf_p, req->key); - LOG_D(PHY,"downlink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb); - LOG_D(PHY, "DLSCH %d in error\n",rdata->dlsch_id); - last = true; - } + LOG_D(PHY, "DLSCH %d in error\n", rdata->dlsch_id); } // if all segments are done @@ -111,7 +113,7 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool 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); @@ -153,18 +155,16 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool } } -void nr_processDLSegment(void* arg) { +static void nr_processDLSegment(void *arg) +{ ldpcDecode_ue_t *rdata = (ldpcDecode_ue_t*) arg; NR_UE_DLSCH_t *dlsch = rdata->dlsch; NR_DL_UE_HARQ_t *harq_process= rdata->harq_process; t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms; int length_dec; - int no_iteration_ldpc; int Kr; int K_bits_F; uint8_t crc_type; - int i; - int j; int r = rdata->segment_r; int A = rdata->A; int E = rdata->E; @@ -174,20 +174,17 @@ void nr_processDLSegment(void* arg) { uint8_t kc = rdata->Kc; uint32_t Tbslbrm = rdata->Tbslbrm; short* dlsch_llr = rdata->dlsch_llr; - rdata->decodeIterations = dlsch->max_ldpc_iterations + 1; - int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__((aligned(32))); - int16_t z [68*384 + 16] __attribute__ ((aligned(16))); + int8_t LDPCoutput[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__((aligned(32))); + int16_t z[68 * 384 + 16] __attribute__((aligned(16))); int8_t l [68*384 + 16] __attribute__ ((aligned(16))); - __m128i *pv = (__m128i*)&z; - __m128i *pl = (__m128i*)&l; - Kr = harq_process->K; K_bits_F = Kr-harq_process->F; t_nrLDPC_time_stats procTime = {0}; - + //if we return before LDPC decoder run, the block is in error + rdata->decodeIterations = dlsch->max_ldpc_iterations + 1; start_meas(&rdata->ts_deinterleave); @@ -226,7 +223,6 @@ void nr_processDLSegment(void* arg) { //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT); stop_meas(&rdata->ts_rate_unmatch); LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n"); - rdata->decodeIterations = dlsch->max_ldpc_iterations + 1; return; } stop_meas(&rdata->ts_rate_unmatch); @@ -255,49 +251,30 @@ void nr_processDLSegment(void* arg) { { start_meas(&rdata->ts_ldpc_decode); //set first 2*Z_c bits to zeros - memset(&z[0],0,2*harq_process->Z*sizeof(int16_t)); + memset(z,0,2*harq_process->Z*sizeof(int16_t)); //set Filler bits - memset((&z[0]+K_bits_F),127,harq_process->F*sizeof(int16_t)); + memset((z+K_bits_F),127,harq_process->F*sizeof(int16_t)); //Move coded bits before filler bits - memcpy((&z[0]+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t)); + memcpy((z+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t)); //skip filler bits - memcpy((&z[0]+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t)); + memcpy((z+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t)); //Saturate coded bits before decoding into 8 bits values - for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1; i+=2, j++) { + __m128i *pv = (__m128i*)&z; + __m128i *pl = (__m128i*)&l; + for (int i=0, j=0; j < ((kc*harq_process->Z)>>4)+1; i+=2, j++) { pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); } //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], llrProcBuf); - no_iteration_ldpc = nrLDPC_decoder(p_decoderParms, - (int8_t *)&pl[0], - llrProcBuf, - &procTime); + 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_D(PHY,"no_iteration_ldpc = %d\n", no_iteration_ldpc); - // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int - if (check_crc((uint8_t *)llrProcBuf,length_dec,harq_process->F,crc_type)) { - LOG_D(PHY,"Segment %u CRC OK\n",r); - if (no_iteration_ldpc > dlsch->max_ldpc_iterations) - no_iteration_ldpc = dlsch->max_ldpc_iterations; - } else { - LOG_D(PHY,"%d.%d CRC NOT OK\n",rdata->proc->frame_rx,rdata->proc->nr_slot_rx); - no_iteration_ldpc = dlsch->max_ldpc_iterations + 1; - } - - if (r==0) { - for (int i=0; i<10; i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t *)llrProcBuf)[i]); - } - - rdata->decodeIterations = no_iteration_ldpc; - - for (int m=0; m < Kr>>3; m ++) { - harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; - } - + if (rdata->decodeIterations <= dlsch->max_ldpc_iterations) + memcpy(harq_process->c[r], LDPCoutput, Kr >> 3); stop_meas(&rdata->ts_ldpc_decode); } } @@ -346,9 +323,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN); //NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0]; - - int nbDecode = 0; - + if (!dlsch_llr) { LOG_E(PHY,"dlsch_decoding.c: NULL dlsch_llr pointer\n"); return(dlsch->max_ldpc_iterations + 1); @@ -406,7 +381,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, harq_process->B = A+24; else harq_process->B = A+16; - + nr_segmentation(NULL, NULL, harq_process->B, @@ -415,7 +390,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, &harq_process->Z, // [hna] Z is Zc &harq_process->F, p_decParams->BG); - + if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*dlsch->Nl) { LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",harq_process->C,harq_process->B); return(-1); @@ -423,6 +398,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD) && (!frame%100)) LOG_I(PHY,"K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, harq_process->Z, dlsch->Nl); + // clear HARQ buffer + for (int i=0; i C; i++) + memset(harq_process->d[i],0,5*8448*sizeof(int16_t)); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT); @@ -450,15 +428,15 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb" Kr_bytes = Kr>>3; offset = 0; - void (*nr_processDLSegment_ptr)(void*) = &nr_processDLSegment; notifiedFIFO_t nf; initNotifiedFIFO(&nf); + set_abort(&harq_process->abort_decode, false); for (r=0; rC; r++) { //printf("start rx segment %d\n",r); E = nr_get_E(G, harq_process->C, dlsch->dlsch_config.qamModOrder, dlsch->Nl, r); decParams.R = nr_get_R_ldpc_decoder(dlsch->dlsch_config.rv, E, decParams.BG, decParams.Z, &harq_process->llrLen, harq_process->DLround); union ldpcReqUnion id = {.s={dlsch->rnti,frame,nr_slot_rx,0,0}}; - notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(ldpcDecode_ue_t), id.p, &nf, nr_processDLSegment_ptr); + notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(ldpcDecode_ue_t), id.p, &nf, &nr_processDLSegment); ldpcDecode_ue_t * rdata=(ldpcDecode_ue_t *) NotifiedFifoData(req); rdata->phy_vars_ue = phy_vars_ue; @@ -484,24 +462,20 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, reset_meas(&rdata->ts_rate_unmatch); reset_meas(&rdata->ts_ldpc_decode); pushTpool(&get_nrUE_params()->Tpool,req); - nbDecode++; - LOG_D(PHY,"Added a block to decode, in pipe: %d\n",nbDecode); + LOG_D(PHY, "Added a block to decode, in pipe: %d\n", r); r_offset += E; offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); ////////////////////////////////////////////////////////////////////////////////////////// } int num_seg_ok = 0; - for (r=0; rC; + while (nbDecode) { notifiedFIFO_elt_t *req=pullTpool(&nf, &get_nrUE_params()->Tpool); if (req == NULL) break; // Tpool has been stopped - bool last = false; - if (r == nbDecode - 1) - last = true; - bool stop = nr_ue_postDecode(phy_vars_ue, req, last, &nf, b_size, b, &num_seg_ok, proc); + nr_ue_postDecode(phy_vars_ue, req, &nf, nbDecode == 1, b_size, b, &num_seg_ok, proc); delNotifiedFIFO_elt(req); - if (stop) - break; + nbDecode--; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_OUT); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index 811fa7711b..2d41e3d600 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -143,6 +143,7 @@ typedef struct { /// Last index of LLR buffer that contains information. /// Used for computing LDPC decoder R int llrLen; + decode_abort_t abort_decode; } NR_DL_UE_HARQ_t; typedef struct { diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 6336c7e5ef..dfadfa2c58 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -960,7 +960,36 @@ extern int sync_var; #define MBSFN_FDD_SF6 0x10 #define MBSFN_FDD_SF7 0x08 #define MBSFN_FDD_SF8 0x04 +typedef struct { + pthread_mutex_t mutex_failure; + bool failed; +} decode_abort_t; +static inline void init_abort(decode_abort_t *ab) +{ + int ret = pthread_mutex_init(&ab->mutex_failure, NULL); + AssertFatal(ret == 0, "mutex failed with %d\n", ret); + ab->failed = false; +} + +static inline bool check_abort(decode_abort_t *ab) +{ + int ret = pthread_mutex_lock(&ab->mutex_failure); + AssertFatal(ret == 0, "mutex failed with %d\n", ret); + bool failed = ab->failed; + ret = pthread_mutex_unlock(&ab->mutex_failure); + AssertFatal(ret == 0, "mutex failed with %d\n", ret); + return failed; +} + +static inline void set_abort(decode_abort_t *ab, bool v) +{ + int ret = pthread_mutex_lock(&ab->mutex_failure); + AssertFatal(ret == 0, "mutex failed with %d\n", ret); + ab->failed = v; + ret = pthread_mutex_unlock(&ab->mutex_failure); + AssertFatal(ret == 0, "mutex failed with %d\n", ret); +} typedef uint8_t(decoder_if_t)(int16_t *y, int16_t *y2, @@ -976,7 +1005,8 @@ typedef uint8_t(decoder_if_t)(int16_t *y, time_stats_t *gamma_stats, time_stats_t *ext_stats, time_stats_t *intl1_stats, - time_stats_t *intl2_stats); + time_stats_t *intl2_stats, + decode_abort_t *abort_decode); typedef uint8_t(encoder_if_t)(uint8_t *input, uint16_t input_length_bytes, diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index c82db65718..4066550d76 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -221,6 +221,7 @@ typedef struct { uint32_t E; /// Number of segments processed so far uint32_t processedSegments; + decode_abort_t abort_decode; /// Last index of LLR buffer that contains information. /// Used for computing LDPC decoder R int llrLen; @@ -774,7 +775,6 @@ typedef struct PHY_VARS_gNB_s { pthread_t L1_tx_thread; int L1_tx_thread_core; struct processingData_L1tx *msgDataTx; - int nbDecode; void *scopeData; /// structure for analyzing high-level RT measurements rt_L1_profiling_t rt_L1_profiling; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index efeba1d546..a789142b0b 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -1228,7 +1228,8 @@ uci_procedures(PHY_VARS_eNB *eNB, } // end loop for (int i = 0; i < NUMBER_OF_UCI_MAX; i++) { } -void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) { +void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) +{ turboDecode_t * rdata=(turboDecode_t *) NotifiedFifoData(req); LTE_eNB_ULSCH_t *ulsch = rdata->eNB->ulsch[rdata->UEid]; @@ -1244,19 +1245,7 @@ void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) { if (decodeSucess) { int Fbytes=(rdata->segment_r==0) ? rdata->Fbits>>3 : 0; int sz=(rdata->Kr>>3) - Fbytes - ((ulsch_harq->C>1)?3:0); - memcpy(ulsch_harq->decodedBytes+rdata->offset, - rdata->decoded_bytes+Fbytes, - sz); - } else { - if ( rdata->nbSegments != ulsch_harq->processedSegments ) { - int nb=abortTpoolJob(proc->threadPool, req->key); - nb+=abortNotifiedFIFOJob(proc->respDecode, req->key); - proc->nbDecode-=nb; - LOG_D(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb); - AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n", - ulsch_harq->processedSegments, nb, rdata->nbSegments); - ulsch_harq->processedSegments=rdata->nbSegments; - } + memcpy(ulsch_harq->decodedBytes + rdata->offset, rdata->decoded_bytes + Fbytes, sz); } // if this UE segments are all done @@ -1276,8 +1265,8 @@ void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) { } } } - - if (!decodeSucess) { + + if (check_abort(&ulsch_harq->abort_decode)) { T(T_ENB_PHY_ULSCH_UE_NACK, T_INT(eNB->Mod_id), T_INT(rdata->frame), T_INT(rdata->subframe), T_INT(ulsch->rnti), T_INT(rdata->harq_pid)); fill_crc_indication(eNB,i,rdata->frame,rdata->subframe,1); // indicate NAK to MAC @@ -1302,28 +1291,28 @@ void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) { * locally in PHY. */ ulsch_harq->handled = 1; - } // ulsch in error - else if(ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions){ - fill_crc_indication(eNB,i,rdata->frame,rdata->subframe,0); // indicate ACK to MAC - fill_rx_indication(eNB,i,rdata->frame,rdata->subframe); // indicate SDU to MAC - ulsch_harq->status = SCH_IDLE; - ulsch->harq_mask &= ~(1 << rdata->harq_pid); - for (int j=0;julsch_stats[j].rnti == ulsch->rnti) { - eNB->ulsch_stats[j].total_bytes_rx+=ulsch_harq->TBS; - for (int aa=0;aaframe_parms.nb_antennas_rx;aa++) { - eNB->ulsch_stats[j].ulsch_power[aa] = dB_fixed_x10(eNB->pusch_vars[rdata->UEid]->ulsch_power[aa]); - eNB->ulsch_stats[j].ulsch_noise_power[aa] = dB_fixed_x10(eNB->pusch_vars[rdata->UEid]->ulsch_noise_power[aa]); - } - break; - } + } // ulsch in error + else if (ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions) { + fill_crc_indication(eNB, i, rdata->frame, rdata->subframe, 0); // indicate ACK to MAC + fill_rx_indication(eNB, i, rdata->frame, rdata->subframe); // indicate SDU to MAC + ulsch_harq->status = SCH_IDLE; + ulsch->harq_mask &= ~(1 << rdata->harq_pid); + for (int j = 0; j < NUMBER_OF_ULSCH_MAX; j++) + if (eNB->ulsch_stats[j].rnti == ulsch->rnti) { + eNB->ulsch_stats[j].total_bytes_rx += ulsch_harq->TBS; + for (int aa = 0; aa < eNB->frame_parms.nb_antennas_rx; aa++) { + eNB->ulsch_stats[j].ulsch_power[aa] = dB_fixed_x10(eNB->pusch_vars[rdata->UEid]->ulsch_power[aa]); + eNB->ulsch_stats[j].ulsch_noise_power[aa] = dB_fixed_x10(eNB->pusch_vars[rdata->UEid]->ulsch_noise_power[aa]); + } + break; + } T (T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(rdata->frame), T_INT(rdata->subframe), T_INT(ulsch->rnti), T_INT(rdata->harq_pid)); - } // ulsch not in error - + } // ulsch not in error + if (ulsch_harq->O_ACK>0) fill_ulsch_harq_indication(eNB,ulsch_harq,ulsch->rnti,rdata->frame,rdata->subframe,ulsch->bundling); - } + } } void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 39e360c79c..d7e9969065 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -232,7 +232,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,0); } -void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) +static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req); NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq; @@ -241,32 +241,22 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[rdata->ulsch_id].harq_process->ulsch_pdu; bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter); ulsch_harq->processedSegments++; - LOG_D(PHY, "processing result of segment: %d, processed %d/%d\n", - rdata->segment_r, ulsch_harq->processedSegments, rdata->nbSegments); - gNB->nbDecode--; - LOG_D(PHY,"remain to decoded in subframe: %d\n", gNB->nbDecode); + LOG_D(PHY, + "processing result of segment: %d, processed %d/%d\n", + rdata->segment_r, + ulsch_harq->processedSegments, + rdata->nbSegments); if (decodeSuccess) { - memcpy(ulsch_harq->b+rdata->offset, - ulsch_harq->c[r], - rdata->Kr_bytes - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0)); + memcpy(ulsch_harq->b + rdata->offset, ulsch_harq->c[r], rdata->Kr_bytes - (ulsch_harq->F >> 3) - ((ulsch_harq->C > 1) ? 3 : 0)); } else { - if ( rdata->nbSegments != ulsch_harq->processedSegments ) { - int nb = abortTpoolJob(&gNB->threadPool, req->key); - nb += abortNotifiedFIFOJob(&gNB->respDecode, req->key); - gNB->nbDecode-=nb; - LOG_D(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb); - LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id); - AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n", - ulsch_harq->processedSegments, nb, rdata->nbSegments); - ulsch_harq->processedSegments=rdata->nbSegments; - } + LOG_D(PHY, "ULSCH %d in error\n", rdata->ulsch_id); } //int dumpsig=0; // if all segments are done if (rdata->nbSegments == ulsch_harq->processedSegments) { - if (decodeSuccess && !gNB->pusch_vars[rdata->ulsch_id].DTX) { + if (!check_abort(&ulsch_harq->abort_decode) && !gNB->pusch_vars[rdata->ulsch_id].DTX) { LOG_D(PHY, "[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (rnti %x, pid %d, ndi %d, status %d, round %d, TBS %d, Max interation " "(all seg) %d)\n", @@ -306,6 +296,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) nr_fill_indication(gNB, ulsch->frame, ulsch->slot, rdata->ulsch_id, rdata->harq_pid, 1, 0); // dumpsig=1; } + ulsch->last_iteration_cnt = rdata->decodeIterations; /* if (ulsch_harq->ulsch_pdu.mcs_index == 0 && dumpsig==1) { int off = ((ulsch_harq->ulsch_pdu.rb_size&1) == 1)? 4:0; @@ -348,13 +339,12 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) } } -void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid) +static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid) { NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[ULSCH_id].harq_process->ulsch_pdu; uint16_t nb_re_dmrs; - uint8_t enable_ldpc_offload = gNB->ldpc_offload_flag; uint16_t start_symbol = pusch_pdu->start_symbol_index; uint16_t number_symbols = pusch_pdu->nr_of_symbols; @@ -407,17 +397,10 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH //---------------------------------------------------------- start_meas(&gNB->ulsch_decoding_stats); - nr_ulsch_decoding(gNB, ULSCH_id, gNB->pusch_vars[ULSCH_id].llr, frame_parms, pusch_pdu, frame_rx, slot_rx, harq_pid, G); - if (enable_ldpc_offload == 0) { - while (gNB->nbDecode > 0) { - notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool); - if (req == NULL) - break; // Tpool has been stopped - nr_postDecode(gNB, req); - delNotifiedFIFO_elt(req); - } - } + int nbDecode = + nr_ulsch_decoding(gNB, ULSCH_id, gNB->pusch_vars[ULSCH_id].llr, frame_parms, pusch_pdu, frame_rx, slot_rx, harq_pid, G); stop_meas(&gNB->ulsch_decoding_stats); + return nbDecode; } @@ -848,6 +831,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } } + int totalDecode = 0; for (int ULSCH_id = 0; ULSCH_id < gNB->max_nb_pusch; ULSCH_id++) { NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id]; NR_UL_gNB_HARQ_t *ulsch_harq = ulsch->harq_process; @@ -944,11 +928,20 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) // LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1); // LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX, 1); - nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, ulsch->harq_pid); + totalDecode += nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, ulsch->harq_pid); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX, 0); } } - + if (totalDecode > 0 && gNB->ldpc_offload_flag == 0) { + while (totalDecode > 0) { + notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool); + if (req == NULL) + break; // Tpool has been stopped + nr_postDecode(gNB, req); + delNotifiedFIFO_elt(req); + totalDecode--; + } + } for (int i = 0; i < gNB->max_nb_srs; i++) { NR_gNB_SRS_t *srs = &gNB->srs[i]; if (srs) { diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 5609f7d608..dc0174c382 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -127,11 +127,16 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, NR_DL_UE_HARQ_t *dl_harq0 = NULL; if ((pdu_type != FAPI_NR_RX_PDU_TYPE_SSB) && dlsch0) { + int t=WS_C_RNTI; + if (pdu_type == FAPI_NR_RX_PDU_TYPE_RAR) + t=WS_RA_RNTI; + if (pdu_type == FAPI_NR_RX_PDU_TYPE_SIB) + t=WS_SI_RNTI; dl_harq0 = &ue->dl_harq_processes[0][dlsch0->dlsch_config.harq_process_nbr]; trace_NRpdu(DIRECTION_DOWNLINK, b, dlsch0->dlsch_config.TBS / 8, - WS_C_RNTI, + t, dlsch0->rnti, proc->frame_rx, proc->nr_slot_rx, @@ -419,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/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index 47ab3c7a91..ee3ecd221d 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -2995,6 +2995,8 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, void copy_harq_proc_struct(LTE_DL_UE_HARQ_t *harq_processes_dest, LTE_DL_UE_HARQ_t *current_harq_processes) { + init_abort(&harq_processes_dest->abort_decode); + set_abort(&harq_processes_dest->abort_decode, check_abort(¤t_harq_processes->abort_decode)); harq_processes_dest->B = current_harq_processes->B ; harq_processes_dest->C = current_harq_processes->C ; harq_processes_dest->Cminus = current_harq_processes->Cminus ; diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 69dcbe728a..4b25863e85 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -91,42 +91,24 @@ void deref_sched_response(int _) exit(1); } -int nr_postDecode_sim(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { +int nr_postDecode_sim(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req, int *nb_ok) +{ ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req); NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq; - NR_gNB_ULSCH_t *ulsch = rdata->ulsch; int r = rdata->segment_r; bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter); ulsch_harq->processedSegments++; - gNB->nbDecode--; if (decodeSuccess) { memcpy(ulsch_harq->b+rdata->offset, ulsch_harq->c[r], rdata->Kr_bytes - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0)); - } else { - if ( rdata->nbSegments != ulsch_harq->processedSegments ) { - int nb=abortTpoolJob(&gNB->threadPool, req->key); - nb+=abortNotifiedFIFOJob(&gNB->respDecode, req->key); - gNB->nbDecode-=nb; - AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n", - ulsch_harq->processedSegments, nb, rdata->nbSegments); - ulsch_harq->processedSegments=rdata->nbSegments; - return 1; - } } - // if all segments are done - if (rdata->nbSegments == ulsch_harq->processedSegments) { - if (decodeSuccess) { - return 0; - } else { - return 1; - } - - } - ulsch->last_iteration_cnt = rdata->decodeIterations; + // if all segments are done + if (rdata->nbSegments == ulsch_harq->processedSegments) + return *nb_ok == rdata->nbSegments; return 0; } @@ -612,13 +594,15 @@ int main(int argc, char **argv) rel15_ul->qam_mod_order, rel15_ul->nrOfLayers); - nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, rel15_ul, - frame, subframe, harq_pid, G); - while (gNB->nbDecode > 0) { - notifiedFIFO_elt_t *req=pullTpool(&gNB->respDecode, &gNB->threadPool); - ret = nr_postDecode_sim(gNB, req); - delNotifiedFIFO_elt(req); - } + int nbDecode = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, rel15_ul, frame, subframe, harq_pid, G); + int nb_ok = 0; + if (nbDecode > 0) + while (nbDecode > 0) { + notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool); + ret = nr_postDecode_sim(gNB, req, &nb_ok); + delNotifiedFIFO_elt(req); + nbDecode--; + } if (ret) n_errors++; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 66460e7a63..f686ce8201 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] = malloc(gNB->frame_parms.samples_per_frame * sizeof(**rxdata)); + 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]; @@ -705,8 +705,7 @@ int main(int argc, char **argv) } // Configure UE - UE = malloc(sizeof(PHY_VARS_NR_UE)); - memset((void*)UE,0,sizeof(PHY_VARS_NR_UE)); + UE = calloc(1, sizeof(PHY_VARS_NR_UE)); PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE**)); PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE*)); PHY_vars_UE_g[0][0] = UE; @@ -756,21 +755,11 @@ int main(int argc, char **argv) nr_phy_data_tx_t phy_data = {0}; - unsigned char *estimated_output_bit; - unsigned char *test_input_bit; uint32_t errors_decoding = 0; - - test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); - estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); - - nr_scheduled_response_t scheduled_response; - fapi_nr_ul_config_request_t ul_config; - fapi_nr_tx_request_t tx_req; - - memset(&scheduled_response, 0, sizeof(scheduled_response)); - memset(&ul_config, 0, sizeof(ul_config)); - memset(&tx_req, 0, sizeof(tx_req)); + nr_scheduled_response_t scheduled_response={0}; + fapi_nr_ul_config_request_t ul_config={0}; + fapi_nr_tx_request_t tx_req={0}; uint8_t ptrs_mcs1 = 2; uint8_t ptrs_mcs2 = 4; @@ -851,7 +840,7 @@ int main(int argc, char **argv) ulsch_input_buffer[0] = 0x31; for (i = 1; i < TBS/8; i++) { - ulsch_input_buffer[i] = (unsigned char) rand(); + ulsch_input_buffer[i] = (unsigned char) uniformrandom(); } uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, Imcs, mcs_table); @@ -1053,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; @@ -1525,10 +1514,10 @@ int main(int argc, char **argv) } for (i = 0; i < TBS; i++) { - estimated_output_bit[i] = (ulsch_gNB->harq_process->b[i / 8] & (1 << (i & 7))) >> (i & 7); - test_input_bit[i] = (UE->ul_harq_processes[harq_pid].b[i / 8] & (1 << (i & 7))) >> (i & 7); + uint8_t estimated_output_bit = (ulsch_gNB->harq_process->b[i / 8] & (1 << (i & 7))) >> (i & 7); + uint8_t test_input_bit = (UE->ul_harq_processes[harq_pid].b[i / 8] & (1 << (i & 7))) >> (i & 7); - if (estimated_output_bit[i] != test_input_bit[i]) { + if (estimated_output_bit != test_input_bit) { /*if(errors_decoding == 0) printf("\x1B[34m""[frame %d][trial %d]\t1st bit in error in decoding = %d\n" "\x1B[0m", frame, trial, i);*/ errors_decoding++; @@ -1663,8 +1652,6 @@ int main(int argc, char **argv) num_dmrs_cdm_grps_no_data); free_MIB_NR(mib); - free(test_input_bit); - free(estimated_output_bit); if (gNB->ldpc_offload_flag) free_nrLDPClib_offload();