Commit 28cff291 authored by Raymond Knopp's avatar Raymond Knopp Committed by Robert Schmidt

Simplify TB_parameters, c, d, d_to_be_cleared

The upcoming LDPC CUDA offload library needs a contiguous buffer instead
of individual segments. Correspondingly, change the interface to
accommodate this need, in the CPU slot decoding library and AAL.
Co-authored-by: default avatarRobert Schmidt <robert.schmidt@openairinterface.org>
Co-authored-by: default avatarJaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Co-authored-by: default avatarRomain Beurdouche <romain.beurdouche@eurecom.fr>
Signed-off-by: default avatarRobert Schmidt <robert.schmidt@openairinterface.org>
parent aab58590
...@@ -8,43 +8,12 @@ ...@@ -8,43 +8,12 @@
#include "common/utils/time_meas.h" #include "common/utils/time_meas.h"
#include "openair1/PHY/CODING/coding_defs.h" #include "openair1/PHY/CODING/coding_defs.h"
#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h"
#include "common/utils/threadPool/thread-pool.h" #include "common/utils/threadPool/thread-pool.h"
#ifndef __NRLDPC_CODING_INTERFACE__H__ #ifndef __NRLDPC_CODING_INTERFACE__H__
#define __NRLDPC_CODING_INTERFACE__H__ #define __NRLDPC_CODING_INTERFACE__H__
/**
* \typedef nrLDPC_segment_decoding_parameters_t
* \struct nrLDPC_segment_decoding_parameters_s
* \brief decoding parameter of segments
* \var E input llr segment size
* \var R code rate indication
* \var llr segment input llr array
* \var d Pointers to code blocks before LDPC decoding (38.212 V15.4.0 section 5.3.2)
* \var d_to_be_cleared
* pointer to the flag used to clear d properly
* when true, clear d after rate dematching
* \var c Pointers to code blocks after LDPC decoding (38.212 V15.4.0 section 5.2.2)
* \var decodeSuccess
* flag indicating that the decoding of the segment was successful
* IT MUST BE FILLED BY THE IMPLEMENTATION
* \var ts_deinterleave deinterleaving time stats
* \var ts_rate_unmatch rate unmatching time stats
* \var ts_ldpc_decode decoding time stats
*/
typedef struct nrLDPC_segment_decoding_parameters_s{
int E;
uint8_t R;
short *llr;
int16_t *d;
bool *d_to_be_cleared;
uint8_t *c;
bool decodeSuccess;
time_stats_t ts_deinterleave;
time_stats_t ts_rate_unmatch;
time_stats_t ts_ldpc_decode;
} nrLDPC_segment_decoding_parameters_t;
/** /**
* \typedef nrLDPC_TB_decoding_parameters_t * \typedef nrLDPC_TB_decoding_parameters_t
* \struct nrLDPC_TB_decoding_parameters_s * \struct nrLDPC_TB_decoding_parameters_s
...@@ -96,7 +65,20 @@ typedef struct nrLDPC_TB_decoding_parameters_s{ ...@@ -96,7 +65,20 @@ typedef struct nrLDPC_TB_decoding_parameters_s{
uint32_t F; uint32_t F;
uint32_t C; uint32_t C;
nrLDPC_segment_decoding_parameters_t *segments; int E;
uint8_t R;
int E2;
uint8_t R2;
int first_rE2;
short *llr;
uint8_t *c;
int16_t *d;
bool d_to_be_cleared;
bool decodeSuccess[NR_LDPC_MAX_NUM_CB];
time_stats_t ts_deinterleave;
time_stats_t ts_rate_unmatch;
time_stats_t ts_seg_prep;
time_stats_t ts_ldpc_decode;
} nrLDPC_TB_decoding_parameters_t; } nrLDPC_TB_decoding_parameters_t;
/** /**
......
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
typedef struct nrLDPC_decoding_parameters_s { typedef struct nrLDPC_decoding_parameters_s {
t_nrLDPC_dec_params decoderParms; t_nrLDPC_dec_params decoderParms;
int r;
uint8_t Qm; uint8_t Qm;
uint8_t Kc; uint8_t Kc;
...@@ -83,16 +84,16 @@ typedef struct nrLDPC_decoding_parameters_s { ...@@ -83,16 +84,16 @@ typedef struct nrLDPC_decoding_parameters_s {
int E; int E;
short *llr; short *llr;
int16_t *d; int16_t *d;
bool *d_to_be_cleared; bool d_to_be_cleared;
uint8_t *c; uint8_t *c;
bool *decodeSuccess; bool *decodeSuccess;
task_ans_t *ans; task_ans_t *ans;
time_stats_t *p_ts_deinterleave; time_stats_t ts_deinterleave;
time_stats_t *p_ts_rate_unmatch; time_stats_t ts_rate_unmatch;
time_stats_t *p_ts_seg_prep; time_stats_t ts_seg_prep;
time_stats_t *p_ts_ldpc_decode; time_stats_t ts_ldpc_decode;
} nrLDPC_decoding_parameters_t; } nrLDPC_decoding_parameters_t;
static void nr_process_decode_segment(void *arg) static void nr_process_decode_segment(void *arg)
...@@ -118,7 +119,7 @@ static void nr_process_decode_segment(void *arg) ...@@ -118,7 +119,7 @@ static void nr_process_decode_segment(void *arg)
//////////////////////////// ulsch_llr =====> ulsch_harq->e ////////////////////////////// //////////////////////////// ulsch_llr =====> ulsch_harq->e //////////////////////////////
start_meas(rdata->p_ts_deinterleave); start_meas(&rdata->ts_deinterleave);
/// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) /// 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]; int16_t harq_e[E];
...@@ -127,9 +128,9 @@ static void nr_process_decode_segment(void *arg) ...@@ -127,9 +128,9 @@ static void nr_process_decode_segment(void *arg)
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
stop_meas(rdata->p_ts_deinterleave); stop_meas(&rdata->ts_deinterleave);
start_meas(rdata->p_ts_rate_unmatch); start_meas(&rdata->ts_rate_unmatch);
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////// nr_rate_matching_ldpc_rx //////////////////////////////// //////////////////////////////// nr_rate_matching_ldpc_rx ////////////////////////////////
...@@ -144,21 +145,28 @@ static void nr_process_decode_segment(void *arg) ...@@ -144,21 +145,28 @@ static void nr_process_decode_segment(void *arg)
harq_e, harq_e,
rdata->C, rdata->C,
rv_index, rv_index,
*rdata->d_to_be_cleared, rdata->d_to_be_cleared,
E, E,
rdata->F, rdata->F,
K - rdata->F - 2 * (p_decoderParms->Z)) K - rdata->F - 2 * (p_decoderParms->Z))
== -1) { == -1) {
stop_meas(rdata->p_ts_rate_unmatch); stop_meas(&rdata->ts_rate_unmatch);
LOG_E(PHY, "nrLDPC_coding_segment_decoder.c: Problem in rate_matching\n"); LOG_E(PHY,
"nrLDPC_coding_segment_decoder.c: Problem in rate_matching BG %d, Z %d, C %d, rv_index %d, E %d, F %d, K%d, K-F-2*Z %d\n",
p_decoderParms->BG,
p_decoderParms->Z,
rdata->C,
rv_index,
E,
rdata->F,
K,
K - rdata->F - 2 * (p_decoderParms->Z));
// Task completed // Task completed
completed_task_ans(rdata->ans); completed_task_ans(rdata->ans);
return; return;
} }
stop_meas(rdata->p_ts_rate_unmatch); stop_meas(&rdata->ts_rate_unmatch);
*rdata->d_to_be_cleared = false;
p_decoderParms->crc_type = crcType(rdata->C, A); p_decoderParms->crc_type = crcType(rdata->C, A);
p_decoderParms->Kprime = lenWithCrc(rdata->C, A); p_decoderParms->Kprime = lenWithCrc(rdata->C, A);
...@@ -168,7 +176,7 @@ static void nr_process_decode_segment(void *arg) ...@@ -168,7 +176,7 @@ static void nr_process_decode_segment(void *arg)
int16_t z[68 * 384 + 16] __attribute__((aligned(16))); int16_t z[68 * 384 + 16] __attribute__((aligned(16)));
start_meas(rdata->p_ts_seg_prep); start_meas(&rdata->ts_seg_prep);
memset(z, 0, 2 * rdata->Z * sizeof(*z)); memset(z, 0, 2 * rdata->Z * sizeof(*z));
// set Filler bits // set Filler bits
memset(z + Kprime, 127, rdata->F * sizeof(*z)); memset(z + Kprime, 127, rdata->F * sizeof(*z));
...@@ -183,7 +191,7 @@ static void nr_process_decode_segment(void *arg) ...@@ -183,7 +191,7 @@ static void nr_process_decode_segment(void *arg)
for (int i = 0, j = 0; j < ((Kc * rdata->Z) >> 4) + 1; i += 2, j++) { for (int i = 0, j = 0; j < ((Kc * rdata->Z) >> 4) + 1; i += 2, j++) {
pl[j] = simde_mm_packs_epi16(pv[i], pv[i + 1]); pl[j] = simde_mm_packs_epi16(pv[i], pv[i + 1]);
} }
stop_meas(rdata->p_ts_seg_prep); stop_meas(&rdata->ts_seg_prep);
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
...@@ -191,16 +199,18 @@ static void nr_process_decode_segment(void *arg) ...@@ -191,16 +199,18 @@ static void nr_process_decode_segment(void *arg)
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// pl =====> llrProcBuf ////////////////////////////////// ////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
start_meas(rdata->p_ts_ldpc_decode); start_meas(&rdata->ts_ldpc_decode);
int decodeIterations = LDPCdecoder(p_decoderParms, l, (uint8_t *)llrProcBuf, p_procTime, rdata->abort_decode); int decodeIterations = LDPCdecoder(p_decoderParms, l, (uint8_t *)llrProcBuf, p_procTime, rdata->abort_decode);
AssertFatal(rdata->c, "rdata->c is null, A %d, K %d\n", rdata->A, rdata->K);
if (decodeIterations < p_decoderParms->numMaxIter) { if (decodeIterations < p_decoderParms->numMaxIter) {
memcpy(rdata->c, llrProcBuf, K >> 3); memcpy(rdata->c, llrProcBuf, K >> 3);
*rdata->decodeSuccess = true; *rdata->decodeSuccess = true;
} else { } else {
LOG_D(PHY, "Decoding failed: K %d, Z %d, rv_index %d\n", K, rdata->Z, rdata->rv_index);
memset(rdata->c, 0, K >> 3); memset(rdata->c, 0, K >> 3);
*rdata->decodeSuccess = false; *rdata->decodeSuccess = false;
} }
stop_meas(rdata->p_ts_ldpc_decode); stop_meas(&rdata->ts_ldpc_decode);
// Task completed // Task completed
completed_task_ans(rdata->ans); completed_task_ans(rdata->ans);
...@@ -217,20 +227,28 @@ int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_de ...@@ -217,20 +227,28 @@ int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_de
decParams.BG = nrLDPC_TB_decoding_parameters->BG; decParams.BG = nrLDPC_TB_decoding_parameters->BG;
decParams.Z = nrLDPC_TB_decoding_parameters->Z; decParams.Z = nrLDPC_TB_decoding_parameters->Z;
decParams.numMaxIter = nrLDPC_TB_decoding_parameters->max_ldpc_iterations; decParams.numMaxIter = nrLDPC_TB_decoding_parameters->max_ldpc_iterations;
decParams.outMode = 0; decParams.outMode = nrLDPC_outMode_BIT;
for (int r = 0; r < nrLDPC_TB_decoding_parameters->C; r++) { for (int r = 0; r < nrLDPC_TB_decoding_parameters->C; r++) {
nrLDPC_decoding_parameters_t *rdata = &((nrLDPC_decoding_parameters_t *)t_info->buf)[t_info->len]; nrLDPC_decoding_parameters_t *rdata = &((nrLDPC_decoding_parameters_t *)t_info->buf)[t_info->len];
DevAssert(t_info->len < t_info->cap); DevAssert(t_info->len < t_info->cap);
rdata->ans = t_info->ans; rdata->ans = t_info->ans;
t_info->len += 1; t_info->len += 1;
int llr_offset;
decParams.R = nrLDPC_TB_decoding_parameters->segments[r].R; if (r < nrLDPC_TB_decoding_parameters->first_rE2) {
decParams.R = nrLDPC_TB_decoding_parameters->R;
rdata->E = nrLDPC_TB_decoding_parameters->E;
llr_offset = r * rdata->E;
} else {
decParams.R = nrLDPC_TB_decoding_parameters->R2;
rdata->E = nrLDPC_TB_decoding_parameters->E2;
llr_offset = nrLDPC_TB_decoding_parameters->first_rE2 * nrLDPC_TB_decoding_parameters->E
+ (r - nrLDPC_TB_decoding_parameters->first_rE2) * rdata->E;
}
rdata->r = r;
rdata->decoderParms = decParams; rdata->decoderParms = decParams;
rdata->llr = nrLDPC_TB_decoding_parameters->segments[r].llr;
rdata->Kc = decParams.BG == 2 ? 52 : 68; rdata->Kc = decParams.BG == 2 ? 52 : 68;
rdata->C = nrLDPC_TB_decoding_parameters->C; rdata->C = nrLDPC_TB_decoding_parameters->C;
rdata->E = nrLDPC_TB_decoding_parameters->segments[r].E;
rdata->A = nrLDPC_TB_decoding_parameters->A; rdata->A = nrLDPC_TB_decoding_parameters->A;
rdata->Qm = nrLDPC_TB_decoding_parameters->Qm; rdata->Qm = nrLDPC_TB_decoding_parameters->Qm;
rdata->K = nrLDPC_TB_decoding_parameters->K; rdata->K = nrLDPC_TB_decoding_parameters->K;
...@@ -239,18 +257,30 @@ int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_de ...@@ -239,18 +257,30 @@ int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_de
rdata->rv_index = nrLDPC_TB_decoding_parameters->rv_index; rdata->rv_index = nrLDPC_TB_decoding_parameters->rv_index;
rdata->tbslbrm = nrLDPC_TB_decoding_parameters->tbslbrm; rdata->tbslbrm = nrLDPC_TB_decoding_parameters->tbslbrm;
rdata->abort_decode = nrLDPC_TB_decoding_parameters->abort_decode; rdata->abort_decode = nrLDPC_TB_decoding_parameters->abort_decode;
rdata->d = nrLDPC_TB_decoding_parameters->segments[r].d; rdata->d = nrLDPC_TB_decoding_parameters->d + r * rdata->Kc * rdata->Z;
rdata->d_to_be_cleared = nrLDPC_TB_decoding_parameters->segments[r].d_to_be_cleared; rdata->d_to_be_cleared = nrLDPC_TB_decoding_parameters->d_to_be_cleared;
rdata->c = nrLDPC_TB_decoding_parameters->segments[r].c; rdata->c = nrLDPC_TB_decoding_parameters->c + r * (rdata->K >> 3);
rdata->decodeSuccess = &nrLDPC_TB_decoding_parameters->segments[r].decodeSuccess; AssertFatal(rdata->c != NULL,
rdata->p_ts_deinterleave = &nrLDPC_TB_decoding_parameters->segments[r].ts_deinterleave; "rdata->c is null, r %d, K %d, A %d, rv_index %d, TB_decoding_parameters->c %p\n",
rdata->p_ts_rate_unmatch = &nrLDPC_TB_decoding_parameters->segments[r].ts_rate_unmatch; r,
rdata->p_ts_ldpc_decode = &nrLDPC_TB_decoding_parameters->segments[r].ts_ldpc_decode; rdata->K,
rdata->A,
rdata->rv_index,
nrLDPC_TB_decoding_parameters->c);
rdata->llr = nrLDPC_TB_decoding_parameters->llr + llr_offset; // rdata->Kc*rdata->Z;
rdata->decodeSuccess = &nrLDPC_TB_decoding_parameters->decodeSuccess[r];
memset(&rdata->ts_deinterleave, 0, sizeof(rdata->ts_deinterleave));
memset(&rdata->ts_rate_unmatch, 0, sizeof(rdata->ts_rate_unmatch));
memset(&rdata->ts_seg_prep, 0, sizeof(rdata->ts_seg_prep));
memset(&rdata->ts_ldpc_decode, 0, sizeof(rdata->ts_ldpc_decode));
reset_meas(&rdata->ts_deinterleave);
reset_meas(&rdata->ts_rate_unmatch);
reset_meas(&rdata->ts_seg_prep);
reset_meas(&rdata->ts_ldpc_decode);
task_t t = {.func = &nr_process_decode_segment, .args = rdata}; task_t t = {.func = &nr_process_decode_segment, .args = rdata};
pushTpool(nrLDPC_slot_decoding_parameters->threadPool, t); pushTpool(nrLDPC_slot_decoding_parameters->threadPool, t);
LOG_D(PHY, "Added a block to decode, in pipe: %d\n", r); LOG_D(PHY, "Added a block to decode, in pipe: %d, rdata->c %p\n", r, rdata->c);
} }
return nrLDPC_TB_decoding_parameters->C; return nrLDPC_TB_decoding_parameters->C;
} }
...@@ -284,12 +314,20 @@ int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_dec ...@@ -284,12 +314,20 @@ int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_dec
// Execute thread pool tasks // Execute thread pool tasks
join_task_ans(t_info.ans); join_task_ans(t_info.ans);
size_t r_t_info = 0;
for (int pusch_id = 0; pusch_id < nrLDPC_slot_decoding_parameters->nb_TBs; pusch_id++) { for (int pusch_id = 0; pusch_id < nrLDPC_slot_decoding_parameters->nb_TBs; pusch_id++) {
nrLDPC_TB_decoding_parameters_t *nrLDPC_TB_decoding_parameters = &nrLDPC_slot_decoding_parameters->TBs[pusch_id]; nrLDPC_TB_decoding_parameters_t *nrLDPC_TB_decoding_parameters = &nrLDPC_slot_decoding_parameters->TBs[pusch_id];
*nrLDPC_TB_decoding_parameters->processedSegments = 0;
for (int r = 0; r < nrLDPC_TB_decoding_parameters->C; r++) { for (int r = 0; r < nrLDPC_TB_decoding_parameters->C; r++) {
if (nrLDPC_TB_decoding_parameters->segments[r].decodeSuccess) { if (nrLDPC_TB_decoding_parameters->decodeSuccess[r])
*nrLDPC_TB_decoding_parameters->processedSegments = *nrLDPC_TB_decoding_parameters->processedSegments + 1; *nrLDPC_TB_decoding_parameters->processedSegments = *nrLDPC_TB_decoding_parameters->processedSegments + 1;
}
nrLDPC_decoding_parameters_t *rdata = &((nrLDPC_decoding_parameters_t *)t_info.buf)[r_t_info];
r_t_info += 1;
merge_meas(&nrLDPC_TB_decoding_parameters->ts_deinterleave, &rdata->ts_deinterleave);
merge_meas(&nrLDPC_TB_decoding_parameters->ts_rate_unmatch, &rdata->ts_rate_unmatch);
merge_meas(&nrLDPC_TB_decoding_parameters->ts_seg_prep, &rdata->ts_seg_prep);
merge_meas(&nrLDPC_TB_decoding_parameters->ts_ldpc_decode, &rdata->ts_ldpc_decode);
} }
} }
return 0; return 0;
......
...@@ -329,11 +329,6 @@ void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_HARQ_PROCESSES], int ...@@ -329,11 +329,6 @@ void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_HARQ_PROCESSES], int
for (int j=0; j < 2; j++) { for (int j=0; j < 2; j++) {
for (int i=0; i<number_of_processes; i++) { for (int i=0; i<number_of_processes; i++) {
for (int r=0; r<a_segments; r++) {
free_and_zero(harq_list[j][i].c[r]);
free_and_zero(harq_list[j][i].d[r]);
}
free_and_zero(harq_list[j][i].b); free_and_zero(harq_list[j][i].b);
free_and_zero(harq_list[j][i].c); free_and_zero(harq_list[j][i].c);
free_and_zero(harq_list[j][i].d); free_and_zero(harq_list[j][i].d);
...@@ -386,14 +381,9 @@ void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_HARQ_PROCESSE ...@@ -386,14 +381,9 @@ void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_HARQ_PROCESSE
init_downlink_harq_status(harq_list[j] + i); init_downlink_harq_status(harq_list[j] + i);
harq_list[j][i].b = malloc16_clear(a_segments * 1056); harq_list[j][i].b = malloc16_clear(a_segments * 1056);
harq_list[j][i].c = malloc16(a_segments*sizeof(uint8_t *)); harq_list[j][i].c = malloc16(a_segments * sizeof(*harq_list[j][i].c) * 1056);
harq_list[j][i].d = malloc16(a_segments*sizeof(int16_t *)); harq_list[j][i].d = malloc16(a_segments * sizeof(*harq_list[j][i].d) * 3 * 8448);
const int sz=5*8448*sizeof(int16_t);
init_abort(&harq_list[j][i].abort_decode); init_abort(&harq_list[j][i].abort_decode);
for (int r=0; r<a_segments; r++) {
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].status = 0;
harq_list[j][i].DLround = 0; harq_list[j][i].DLround = 0;
} }
......
...@@ -47,10 +47,6 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch, uint16_t N_RB_UL) ...@@ -47,10 +47,6 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch, uint16_t N_RB_UL)
free_and_zero(ulsch->harq_process->b); free_and_zero(ulsch->harq_process->b);
ulsch->harq_process->b = NULL; ulsch->harq_process->b = NULL;
} }
for (int r = 0; r < a_segments; r++) {
free_and_zero(ulsch->harq_process->c[r]);
free_and_zero(ulsch->harq_process->d[r]);
}
free_and_zero(ulsch->harq_process->c); free_and_zero(ulsch->harq_process->c);
free_and_zero(ulsch->harq_process->d); free_and_zero(ulsch->harq_process->d);
free_and_zero(ulsch->harq_process->d_to_be_cleared); free_and_zero(ulsch->harq_process->d_to_be_cleared);
...@@ -79,12 +75,9 @@ NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL) ...@@ -79,12 +75,9 @@ NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL)
init_abort(&harq->abort_decode); init_abort(&harq->abort_decode);
ulsch.harq_process = harq; ulsch.harq_process = harq;
harq->b = malloc16_clear(ulsch_bytes * sizeof(*harq->b)); harq->b = malloc16_clear(ulsch_bytes * sizeof(*harq->b));
harq->c = malloc16_clear(a_segments * sizeof(*harq->c)); // Allocate one contiguous buffer fr all c/d arrays to simplify addressing for GPU LDPC offload
harq->d = malloc16_clear(a_segments * sizeof(*harq->d)); harq->c = malloc16_clear(a_segments * 8448 * sizeof(*harq->c));
for (int r = 0; r < a_segments; r++) { harq->d = malloc16_clear(a_segments * 68 * 384 * sizeof(*harq->d));
harq->c[r] = malloc16_clear(8448 * sizeof(*harq->c[r]));
harq->d[r] = malloc16_clear(68 * 384 * sizeof(*harq->d[r]));
}
harq->d_to_be_cleared = calloc(a_segments, sizeof(bool)); harq->d_to_be_cleared = calloc(a_segments, sizeof(bool));
AssertFatal(harq->d_to_be_cleared != NULL, "out of memory\n"); AssertFatal(harq->d_to_be_cleared != NULL, "out of memory\n");
return (ulsch); return (ulsch);
...@@ -223,9 +216,6 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -223,9 +216,6 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
set_abort(&harq_process->abort_decode, false); set_abort(&harq_process->abort_decode, false);
} }
nrLDPC_segment_decoding_parameters_t segments[nb_pusch][max_num_segments];
memset(segments, 0, sizeof(segments));
for (uint8_t pusch_id = 0; pusch_id < nb_pusch; pusch_id++) { for (uint8_t pusch_id = 0; pusch_id < nb_pusch; pusch_id++) {
uint8_t ULSCH_id = ULSCH_ids[pusch_id]; uint8_t ULSCH_id = ULSCH_ids[pusch_id];
NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id]; NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
...@@ -238,66 +228,79 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -238,66 +228,79 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
} }
nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pusch_id]; nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pusch_id];
TB_parameters->segments = segments[pusch_id];
uint32_t r_offset = 0; TB_parameters->llr = ulsch_llr;
TB_parameters->d = harq_process->d;
TB_parameters->c = harq_process->c;
TB_parameters->E = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, TB_parameters->nb_layers, 0);
TB_parameters->first_rE2 = TB_parameters->C;
TB_parameters->E2 = TB_parameters->E;
TB_parameters->R = nr_get_R_ldpc_decoder(TB_parameters->rv_index,
TB_parameters->E,
TB_parameters->BG,
TB_parameters->Z,
&harq_process->llrLen,
harq_process->round);
for (int r = 0; r < TB_parameters->C; r++)
TB_parameters->decodeSuccess[r] = false;
TB_parameters->d_to_be_cleared = harq_process->harq_to_be_cleared;
reset_meas(&TB_parameters->ts_deinterleave);
reset_meas(&TB_parameters->ts_rate_unmatch);
reset_meas(&TB_parameters->ts_seg_prep);
reset_meas(&TB_parameters->ts_ldpc_decode);
for (int r = 0; r < TB_parameters->C; r++) { for (int r = 0; r < TB_parameters->C; r++) {
nrLDPC_segment_decoding_parameters_t *segment_parameters = &TB_parameters->segments[r]; int Etmp = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, TB_parameters->nb_layers, r);
segment_parameters->E = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, TB_parameters->nb_layers, r); if (TB_parameters->E != Etmp) {
segment_parameters->R = nr_get_R_ldpc_decoder(TB_parameters->rv_index, TB_parameters->E2 = Etmp;
segment_parameters->E, TB_parameters->R2 = nr_get_R_ldpc_decoder(TB_parameters->rv_index,
TB_parameters->BG, TB_parameters->E2,
TB_parameters->Z, TB_parameters->BG,
&harq_process->llrLen, TB_parameters->Z,
harq_process->round); &harq_process->llrLen,
segment_parameters->llr = ulsch_llr + r_offset; harq_process->round);
segment_parameters->d = harq_process->d[r]; TB_parameters->first_rE2 = r;
segment_parameters->d_to_be_cleared = &harq_process->d_to_be_cleared[r]; break;
segment_parameters->c = harq_process->c[r];
segment_parameters->decodeSuccess = false;
reset_meas(&segment_parameters->ts_deinterleave);
reset_meas(&segment_parameters->ts_rate_unmatch);
reset_meas(&segment_parameters->ts_ldpc_decode);
r_offset += segment_parameters->E;
}
if (harq_process->harq_to_be_cleared) {
for (int r = 0; r < TB_parameters->C; r++) {
harq_process->d_to_be_cleared[r] = true;
} }
harq_process->harq_to_be_cleared = false;
} }
} }
int ret_decoder = phy_vars_gNB->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters); int ret_decoder = phy_vars_gNB->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters);
// post decode // post decode
for (uint8_t pusch_id = 0; pusch_id < nb_pusch; pusch_id++) { for (uint8_t pusch_id = 0; pusch_id < nb_pusch; pusch_id++) {
uint8_t ULSCH_id = ULSCH_ids[pusch_id]; uint8_t ULSCH_id = ULSCH_ids[pusch_id];
NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id]; NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process; NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
nrLDPC_TB_decoding_parameters_t TB_parameters = TBs[pusch_id]; nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pusch_id];
uint32_t offset = 0; uint32_t offset = 0, r_offset = 0;
for (int r = 0; r < TB_parameters.C; r++) { bool crcok = true;
nrLDPC_segment_decoding_parameters_t nrLDPC_segment_decoding_parameters = TB_parameters.segments[r]; LOG_D(PHY, "C = %d\n", TB_parameters->C);
// Copy c to b in case of decoding success for (int r = 0; r < TB_parameters->C; r++) {
if (nrLDPC_segment_decoding_parameters.decodeSuccess) { LOG_D(PHY, "Segment %d %d\n", r, TB_parameters->decodeSuccess[r]);
if (TB_parameters->decodeSuccess[r] == false) {
LOG_D(PHY, "Segment %d/%d in error\n", r, TB_parameters->C);
crcok = false;
break;
}
}
if (crcok) {
for (int r = 0; r < TB_parameters->C; r++) {
// Copy c to b in case of decoding success
memcpy(harq_process->b + offset, memcpy(harq_process->b + offset,
harq_process->c[r], harq_process->c + r_offset,
(harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); (harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
} else { offset += ((harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
LOG_D(PHY, "uplink segment error %d/%d\n", r, harq_process->C); r_offset += (harq_process->K >> 3);
LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
} }
offset += ((harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); } else {
LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
merge_meas(&phy_vars_gNB->ts_deinterleave, &nrLDPC_segment_decoding_parameters.ts_deinterleave);
merge_meas(&phy_vars_gNB->ts_rate_unmatch, &nrLDPC_segment_decoding_parameters.ts_rate_unmatch);
merge_meas(&phy_vars_gNB->ts_ldpc_decode, &nrLDPC_segment_decoding_parameters.ts_ldpc_decode);
} }
merge_meas(&phy_vars_gNB->ts_deinterleave, &TB_parameters->ts_deinterleave);
merge_meas(&phy_vars_gNB->ts_rate_unmatch, &TB_parameters->ts_rate_unmatch);
merge_meas(&phy_vars_gNB->ts_seg_prep, &TB_parameters->ts_seg_prep);
merge_meas(&phy_vars_gNB->ts_ldpc_decode, &TB_parameters->ts_ldpc_decode);
harq_process->harq_to_be_cleared = false;
} }
return ret_decoder; return ret_decoder;
......
...@@ -69,11 +69,11 @@ typedef struct { ...@@ -69,11 +69,11 @@ typedef struct {
NR_SCH_status_t status; NR_SCH_status_t status;
/// Pointer to the payload (38.212 V15.4.0 section 5.1) /// Pointer to the payload (38.212 V15.4.0 section 5.1)
uint8_t *b; uint8_t *b;
/// Pointers to transport block segments /// Pointer to transport block segments
uint8_t **c; uint8_t *c;
/// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) /// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
/// Accumulates the soft bits for each round to increase decoding success (HARQ) /// Accumulates the soft bits for each round to increase decoding success (HARQ)
int16_t **d; int16_t *d;
/// Index of current HARQ round for this DLSCH /// Index of current HARQ round for this DLSCH
uint8_t DLround; uint8_t DLround;
/// Number of code segments /// Number of code segments
......
...@@ -133,16 +133,16 @@ typedef struct { ...@@ -133,16 +133,16 @@ typedef struct {
bool harq_to_be_cleared; bool harq_to_be_cleared;
/// Pointer to the payload (38.212 V15.4.0 section 5.1) /// Pointer to the payload (38.212 V15.4.0 section 5.1)
uint8_t *b; uint8_t *b;
/// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2) /// Pointer to aggregated code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2)
uint8_t **c; uint8_t *c;
/// Number of bits in each code block (38.212 V15.4.0 section 5.2.2) /// Number of bits in each code block (38.212 V15.4.0 section 5.2.2)
uint32_t K; uint32_t K;
/// Number of "Filler" bits added in the code block segmentation (38.212 V15.4.0 section 5.2.2) /// Number of "Filler" bits added in the code block segmentation (38.212 V15.4.0 section 5.2.2)
uint32_t F; uint32_t F;
/// Number of code blocks after code block segmentation (38.212 V15.4.0 section 5.2.2) /// Number of code blocks after code block segmentation (38.212 V15.4.0 section 5.2.2)
uint32_t C; uint32_t C;
/// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2) /// Pointers to aggregated code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2)
int16_t **d; int16_t *d;
/// flag used to clear d properly (together with harq_to_be_cleared above) /// flag used to clear d properly (together with harq_to_be_cleared above)
/// set to true in nr_ulsch_decoding() when harq_to_be_cleared is true /// set to true in nr_ulsch_decoding() when harq_to_be_cleared is true
/// when true, clear d in the next call to function nr_rate_matching_ldpc_rx() /// when true, clear d in the next call to function nr_rate_matching_ldpc_rx()
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
FN(DLSCH_CHANNEL_ESTIMATION_STATS),\ FN(DLSCH_CHANNEL_ESTIMATION_STATS),\
FN(DLSCH_DECODING_STATS),\ FN(DLSCH_DECODING_STATS),\
FN(DLSCH_RATE_UNMATCHING_STATS),\ FN(DLSCH_RATE_UNMATCHING_STATS),\
FN(DLSCH_SEG_PREP_STATS),\
FN(DLSCH_LDPC_DECODING_STATS),\ FN(DLSCH_LDPC_DECODING_STATS),\
FN(DLSCH_DEINTERLEAVING_STATS),\ FN(DLSCH_DEINTERLEAVING_STATS),\
FN(DLSCH_EXTRACT_RBS_STATS),\ FN(DLSCH_EXTRACT_RBS_STATS),\
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment