Merge remote-tracking branch 'origin/remove-thread-pool-abort' into integration_2023_w24
This commit is contained in:
+5
-1
@@ -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()
|
||||
|
||||
@@ -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<module name><module version>.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<module name><module version>.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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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/
|
||||
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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/
|
||||
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -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 .
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -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.* .
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<n_segments;j++) {
|
||||
start_meas(time_decoder);
|
||||
n_iter = nrLDPC_decoder(&decParams[j], (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], &decoder_profiler);
|
||||
set_abort(&dec_abort, false);
|
||||
n_iter = nrLDPC_decoder(&decParams[j],
|
||||
(int8_t *)channel_output_fixed[j],
|
||||
(int8_t *)estimated_output[j],
|
||||
&decoder_profiler,
|
||||
&dec_abort);
|
||||
stop_meas(time_decoder);
|
||||
//count errors
|
||||
if ( memcmp(estimated_output[j], test_input[j], block_length/8 ) != 0 ) {
|
||||
@@ -429,7 +435,9 @@ int main(int argc, char *argv[])
|
||||
unsigned int errors, errors_bit, crc_misses;
|
||||
double errors_bit_uncoded;
|
||||
short block_length=8448; // decoder supports length: 1201 -> 1280, 2401 -> 2560
|
||||
char *ldpc_version=NULL; /* version of the ldpc decoder library to use (XXX suffix to use when loading libldpc_XXX.so */
|
||||
// default to check output inside ldpc, the NR version checks the outer CRC defined by 3GPP
|
||||
char *ldpc_version = "_parityCheck";
|
||||
/* version of the ldpc decoder library to use (XXX suffix to use when loading libldpc_XXX.so */
|
||||
short max_iterations=5;
|
||||
int n_segments=1;
|
||||
//double rate=0.333;
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<M; i++)
|
||||
{
|
||||
*p_out++ = simde_mm256_and_si256(*p_ones, simde_mm256_cmpgt_epi8(*p_zeros, *p_llrOut));
|
||||
p_llrOut++;
|
||||
}
|
||||
for (int i = 0; i < M; i++) {
|
||||
*p_out++ = simde_mm256_and_si256(*p_ones, simde_mm256_cmpgt_epi8(*p_zeros, *p_llrOut));
|
||||
p_llrOut++;
|
||||
}
|
||||
|
||||
if (Mr > 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<Mr; i++)
|
||||
{
|
||||
if (p_llrOut8[i] < 0)
|
||||
{
|
||||
p_out8[i] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_out8[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < Mr; i++)
|
||||
p_out8[i] = p_llrOut8[i] < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2778,44 +2762,29 @@ static inline void nrLDPC_llr2bitPacked(int8_t* out, int8_t* llrOut, uint16_t nu
|
||||
{
|
||||
/** Vector of indices for shuffling input */
|
||||
const uint8_t constShuffle_256_epi8[32] __attribute__ ((aligned(32))) = {7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8};
|
||||
const __m256i* p_shuffle = (__m256i*)constShuffle_256_epi8;
|
||||
|
||||
__m256i* p_llrOut = (__m256i*) llrOut;
|
||||
uint32_t* p_bits = (uint32_t*) out;
|
||||
__m256i inPerm;
|
||||
int8_t* p_llrOut8;
|
||||
uint32_t bitsTmp = 0;
|
||||
uint32_t i;
|
||||
uint32_t M = numLLR>>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<M; i++)
|
||||
{
|
||||
// Move LSB to MSB on 8 bits
|
||||
inPerm = simde_mm256_shuffle_epi8(*p_llrOut,*p_shuffle);
|
||||
// Hard decision
|
||||
*p_bits++ = simde_mm256_movemask_epi8(inPerm);
|
||||
p_llrOut++;
|
||||
for (uint32_t i = 0; i < M; i++) {
|
||||
// Move LSB to MSB on 8 bits
|
||||
const __m256i inPerm = simde_mm256_shuffle_epi8(*p_llrOut, *p_shuffle);
|
||||
// Hard decision
|
||||
*p_bits++ = simde_mm256_movemask_epi8(inPerm);
|
||||
p_llrOut++;
|
||||
}
|
||||
|
||||
if (Mr > 0)
|
||||
{
|
||||
// Remaining LLRs that do not fit in multiples of 32 bytes
|
||||
p_llrOut8 = (int8_t*) p_llrOut;
|
||||
|
||||
for (i=0; i<Mr; i++)
|
||||
{
|
||||
if (p_llrOut8[i] < 0)
|
||||
{
|
||||
bitsTmp |= (1<<((7-i) + (16*(i/8))));
|
||||
}
|
||||
else
|
||||
{
|
||||
bitsTmp |= (0<<((7-i) + (16*(i/8))));
|
||||
}
|
||||
}
|
||||
// Remaining LLRs that do not fit in multiples of 32 bytes
|
||||
if (Mr) {
|
||||
const int8_t* p_llrOut8 = (int8_t*)p_llrOut;
|
||||
uint32_t bitsTmp = 0;
|
||||
for (uint32_t i = 0; i < Mr; i++)
|
||||
bitsTmp |= (p_llrOut8[i] < 0) << ((7 - i) + (16 * (i / 8)));
|
||||
*p_bits = bitsTmp;
|
||||
}
|
||||
*p_bits = bitsTmp;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "nrLDPC_mPass.h"
|
||||
#include "nrLDPC_cnProc.h"
|
||||
#include "nrLDPC_bnProc.h"
|
||||
#include "openair1/PHY/CODING/coding_defs.h"
|
||||
#define UNROLL_CN_PROC 1
|
||||
#define UNROLL_BN_PROC 1
|
||||
#define UNROLL_BN_PROC_PC 1
|
||||
@@ -106,35 +107,42 @@
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define NR_LDPC_ENABLE_PARITY_CHECK
|
||||
//#define NR_LDPC_PROFILER_DETAIL
|
||||
//#define NR_LDPC_ENABLE_PARITY_CHECK
|
||||
//#define NR_LDPC_PROFILER_DETAIL(a) a
|
||||
#define NR_LDPC_PROFILER_DETAIL(a)
|
||||
|
||||
#ifdef NR_LDPC_DEBUG_MODE
|
||||
#include "nrLDPC_tools/nrLDPC_debug.h"
|
||||
#endif
|
||||
|
||||
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);
|
||||
int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type);
|
||||
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);
|
||||
void nrLDPC_initcall(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out) {
|
||||
}
|
||||
int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, t_nrLDPC_time_stats* p_profiler)
|
||||
int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams,
|
||||
int8_t* p_llr,
|
||||
int8_t* p_out,
|
||||
t_nrLDPC_time_stats* p_profiler,
|
||||
decode_abort_t* ab)
|
||||
{
|
||||
uint32_t numLLR;
|
||||
uint32_t numIter = 0;
|
||||
t_nrLDPC_lut lut;
|
||||
t_nrLDPC_lut* p_lut = &lut;
|
||||
uint32_t numLLR;
|
||||
t_nrLDPC_lut lut;
|
||||
t_nrLDPC_lut* p_lut = &lut;
|
||||
|
||||
// Initialize decoder core(s) with correct LUTs
|
||||
numLLR = nrLDPC_init(p_decParams, p_lut);
|
||||
|
||||
// Launch LDPC decoder core for one segment
|
||||
numIter = nrLDPC_decoder_core(p_llr, p_out, numLLR, p_lut, p_decParams, p_profiler);
|
||||
// Initialize decoder core(s) with correct LUTs
|
||||
numLLR = nrLDPC_init(p_decParams, p_lut);
|
||||
|
||||
// Launch LDPC decoder core for one segment
|
||||
int numIter = nrLDPC_decoder_core(p_llr, p_out, numLLR, p_lut, p_decParams, p_profiler, ab);
|
||||
if (numIter > p_decParams->numMaxIter) {
|
||||
LOG_D(PHY, "set abort: %d, %d\n", numIter, p_decParams->numMaxIter);
|
||||
set_abort(ab, true);
|
||||
}
|
||||
return numIter;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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: <mailto:sebastian.wagner@tcl.com>
|
||||
* \date 07-12-2018
|
||||
* \version 1.0
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifndef __NR_LDPC_INIT_MEM__H__
|
||||
#define __NR_LDPC_INIT_MEM__H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#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
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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; r<a_segments; r++) {
|
||||
harq_list[j][i].c[r] = malloc16(1056);
|
||||
harq_list[j][i].d[r] = malloc16(sz);
|
||||
if (harq_list[j][i].c[r])
|
||||
memset(harq_list[j][i].c[r],0,1056);
|
||||
else
|
||||
AssertFatal(true, "Unable to reset harq memory \"c\"\n");
|
||||
|
||||
if (harq_list[j][i].d[r])
|
||||
memset(harq_list[j][i].d[r], 0, sz);
|
||||
else
|
||||
AssertFatal(true, "Unable to reset harq memory \"d\"\n");
|
||||
harq_list[j][i].c[r] = malloc16_clear(1056);
|
||||
harq_list[j][i].d[r] = malloc16_clear(sz);
|
||||
}
|
||||
harq_list[j][i].status = 0;
|
||||
harq_list[j][i].DLround = 0;
|
||||
|
||||
@@ -327,6 +327,7 @@ typedef struct {
|
||||
uint32_t repetition_number ;
|
||||
// PUSCH Total number of repetitions
|
||||
uint32_t total_number_of_repetitions;
|
||||
decode_abort_t abort_decode;
|
||||
} LTE_UL_eNB_HARQ_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -538,20 +538,6 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB,
|
||||
uint8_t Nbundled,
|
||||
uint8_t 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
|
||||
*/
|
||||
int ulsch_decoding_data(PHY_VARS_eNB *eNB,
|
||||
L1_rxtx_proc_t *proc,
|
||||
int UE_id,
|
||||
int harq_pid,
|
||||
int llr8_flag);
|
||||
|
||||
void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB,
|
||||
L1_rxtx_proc_t *proc,
|
||||
int16_t amp);
|
||||
|
||||
@@ -113,6 +113,7 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin
|
||||
|
||||
if (ulsch->harq_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; r<ulsch_harq->C; r++) {
|
||||
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
|
||||
// Get Turbo interleaver parameters
|
||||
|
||||
@@ -106,9 +106,10 @@ LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_
|
||||
for (i=0; i<Mdlharq; i++) {
|
||||
// printf("new_ue_dlsch: Harq process %d\n",i);
|
||||
dlsch->harq_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; r<harq_process->C; r++) {
|
||||
// Get Turbo interleaver parameters
|
||||
if (r<harq_process->Cminus)
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 <harq_process->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; r<harq_process->C; 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; r<nbDecode; r++) {
|
||||
int nbDecode = harq_process->C;
|
||||
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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;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;
|
||||
}
|
||||
} // 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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user