remove generic thread pool abort
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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 ) {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -118,11 +119,20 @@
|
||||
#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;
|
||||
@@ -133,8 +143,9 @@ int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_
|
||||
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);
|
||||
|
||||
numIter = nrLDPC_decoder_core(p_llr, p_out, numLLR, p_lut, p_decParams, p_profiler, ab);
|
||||
if (numIter > p_decParams->numMaxIter)
|
||||
set_abort(ab, true);
|
||||
return numIter;
|
||||
}
|
||||
|
||||
@@ -147,7 +158,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;
|
||||
@@ -478,8 +495,9 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
|
||||
while ( (i < numMaxIter) && (pcRes != 0) ) {
|
||||
// Increase iteration counter
|
||||
i++;
|
||||
|
||||
// CN processing
|
||||
if (check_abort(ab))
|
||||
return numMaxIter + 2;
|
||||
// CN processing
|
||||
#ifdef NR_LDPC_PROFILER_DETAIL
|
||||
start_meas(&p_profiler->cnProc);
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,170 +119,160 @@ 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)));
|
||||
|
||||
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;
|
||||
rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, (int8_t *)&pl[0], llrProcBuf, p_procTime, &ulsch_harq->abort_decode);
|
||||
|
||||
if (rdata->decodeIterations == p_decoderParms->numMaxIter+1 ) {
|
||||
// We have not decoded succesfully and we have not aborted
|
||||
// We check the CRC, itf it is ok, let's assume the payload is correctly decoded
|
||||
// (so the remaining errors are only in the redundancy (parity) bits)
|
||||
if (check_crc((uint8_t *)llrProcBuf, length_dec, ulsch_harq->F, crc_type)) {
|
||||
PRINT_CRC_CHECK(LOG_I(PHY,"Segment %d CRC OK, iterations %d/%d\n",r,rdata->decodeIterations,max_ldpc_iterations));
|
||||
rdata->decodeIterations = p_decoderParms->numMaxIter;
|
||||
} else {
|
||||
PRINT_CRC_CHECK(LOG_I(PHY,"CRC NOK\n"));
|
||||
rdata->decodeIterations = max_ldpc_iterations + 1;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
|
||||
NR_gNB_PUSCH *pusch = &phy_vars_gNB->pusch_vars[ULSCH_id];
|
||||
@@ -284,14 +280,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
|
||||
if (!harq_process) {
|
||||
LOG_E(PHY,"ulsch_decoding.c: NULL harq_process pointer\n");
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
uint8_t dtx_det = 0;
|
||||
|
||||
int Kr;
|
||||
int Kr_bytes;
|
||||
|
||||
phy_vars_gNB->nbDecode = 0;
|
||||
|
||||
harq_process->processedSegments = 0;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
@@ -303,7 +298,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
|
||||
if (!ulsch_llr) {
|
||||
LOG_E(PHY,"ulsch_decoding.c: NULL ulsch_llr pointer\n");
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,1);
|
||||
@@ -383,7 +378,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);
|
||||
@@ -425,7 +420,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);
|
||||
@@ -446,8 +441,8 @@ 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;
|
||||
@@ -472,8 +467,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
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;
|
||||
decodeIterations = ulsch->max_ldpc_iterations + 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
harq_process->d_to_be_cleared[r] = false;
|
||||
@@ -491,7 +486,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
pl[j] = _mm_packs_epi16(pv[i], pv[i + 1]);
|
||||
}
|
||||
|
||||
no_iteration_ldpc = nrLDPC_decoder(&decParams, (int8_t *)pl, llrProcBuf, p_procTime);
|
||||
decodeIterations = nrLDPC_decoder(&decParams, (int8_t *)pl, llrProcBuf, p_procTime, &harq_process->abort_decode);
|
||||
}
|
||||
|
||||
for (int m = 0; m < Kr >> 3; m++) {
|
||||
@@ -499,16 +494,12 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
}
|
||||
|
||||
if (check_crc((uint8_t *)llrProcBuf, length_dec, harq_process->F, crc_type)) {
|
||||
#ifdef PRINT_CRC_CHECK
|
||||
LOG_I(PHY, "Segment %d CRC OK\n", r);
|
||||
#endif
|
||||
no_iteration_ldpc = 2;
|
||||
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;
|
||||
}
|
||||
//}
|
||||
|
||||
r_offset += E;
|
||||
@@ -521,9 +512,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 +547,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 +582,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
|
||||
@@ -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,45 @@ 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);
|
||||
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];
|
||||
}
|
||||
LOG_W(PHY,"rdata->decodeIterations = %d\n", rdata->decodeIterations);
|
||||
if (rdata->decodeIterations < dlsch->max_ldpc_iterations + 2) {
|
||||
// We have not aborted the decoding
|
||||
if (check_crc((uint8_t *)LDPCoutput, length_dec, harq_process->F, crc_type)) {
|
||||
LOG_D(PHY, "Segment %u CRC OK\n", r);
|
||||
if (rdata->decodeIterations > dlsch->max_ldpc_iterations) {
|
||||
LOG_W(PHY, "force ok\n");
|
||||
rdata->decodeIterations = dlsch->max_ldpc_iterations;
|
||||
}
|
||||
} else {
|
||||
LOG_D(PHY, "%d.%d CRC NOT OK, iter %d\n", rdata->proc->frame_rx, rdata->proc->nr_slot_rx, rdata->decodeIterations);
|
||||
rdata->decodeIterations = dlsch->max_ldpc_iterations + 1;
|
||||
}
|
||||
} else
|
||||
LOG_D(PHY, "%d.%d another segment failure aborted this decode\n", rdata->proc->frame_rx, rdata->proc->nr_slot_rx);
|
||||
|
||||
if (rdata->decodeIterations <= dlsch->max_ldpc_iterations)
|
||||
memcpy(harq_process->c[r], LDPCoutput, Kr >> 3);
|
||||
stop_meas(&rdata->ts_ldpc_decode);
|
||||
}
|
||||
}
|
||||
@@ -346,9 +338,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 +396,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 +405,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 +413,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 +443,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 +477,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,
|
||||
|
||||
@@ -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),1);
|
||||
|
||||
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(sizeof(PHY_VARS_NR_UE), 1);
|
||||
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);
|
||||
@@ -1524,10 +1513,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++;
|
||||
@@ -1662,8 +1651,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