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 @@
#include "common/utils/time_meas.h"
#include "openair1/PHY/CODING/coding_defs.h"
#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h"
#include "common/utils/threadPool/thread-pool.h"
#ifndef __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
* \struct nrLDPC_TB_decoding_parameters_s
......@@ -96,7 +65,20 @@ typedef struct nrLDPC_TB_decoding_parameters_s{
uint32_t F;
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;
/**
......
......@@ -66,6 +66,7 @@
typedef struct nrLDPC_decoding_parameters_s {
t_nrLDPC_dec_params decoderParms;
int r;
uint8_t Qm;
uint8_t Kc;
......@@ -83,16 +84,16 @@ typedef struct nrLDPC_decoding_parameters_s {
int E;
short *llr;
int16_t *d;
bool *d_to_be_cleared;
bool d_to_be_cleared;
uint8_t *c;
bool *decodeSuccess;
task_ans_t *ans;
time_stats_t *p_ts_deinterleave;
time_stats_t *p_ts_rate_unmatch;
time_stats_t *p_ts_seg_prep;
time_stats_t *p_ts_ldpc_decode;
time_stats_t ts_deinterleave;
time_stats_t ts_rate_unmatch;
time_stats_t ts_seg_prep;
time_stats_t ts_ldpc_decode;
} nrLDPC_decoding_parameters_t;
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 //////////////////////////////
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)
int16_t harq_e[E];
......@@ -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 ////////////////////////////////
......@@ -144,21 +145,28 @@ static void nr_process_decode_segment(void *arg)
harq_e,
rdata->C,
rv_index,
*rdata->d_to_be_cleared,
rdata->d_to_be_cleared,
E,
rdata->F,
K - rdata->F - 2 * (p_decoderParms->Z))
== -1) {
stop_meas(rdata->p_ts_rate_unmatch);
LOG_E(PHY, "nrLDPC_coding_segment_decoder.c: Problem in rate_matching\n");
stop_meas(&rdata->ts_rate_unmatch);
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
completed_task_ans(rdata->ans);
return;
}
stop_meas(rdata->p_ts_rate_unmatch);
*rdata->d_to_be_cleared = false;
stop_meas(&rdata->ts_rate_unmatch);
p_decoderParms->crc_type = crcType(rdata->C, A);
p_decoderParms->Kprime = lenWithCrc(rdata->C, A);
......@@ -168,7 +176,7 @@ static void nr_process_decode_segment(void *arg)
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));
// set Filler bits
memset(z + Kprime, 127, rdata->F * sizeof(*z));
......@@ -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++) {
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)
//////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// 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);
AssertFatal(rdata->c, "rdata->c is null, A %d, K %d\n", rdata->A, rdata->K);
if (decodeIterations < p_decoderParms->numMaxIter) {
memcpy(rdata->c, llrProcBuf, K >> 3);
*rdata->decodeSuccess = true;
} 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);
*rdata->decodeSuccess = false;
}
stop_meas(rdata->p_ts_ldpc_decode);
stop_meas(&rdata->ts_ldpc_decode);
// Task completed
completed_task_ans(rdata->ans);
......@@ -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.Z = nrLDPC_TB_decoding_parameters->Z;
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++) {
nrLDPC_decoding_parameters_t *rdata = &((nrLDPC_decoding_parameters_t *)t_info->buf)[t_info->len];
DevAssert(t_info->len < t_info->cap);
rdata->ans = t_info->ans;
t_info->len += 1;
decParams.R = nrLDPC_TB_decoding_parameters->segments[r].R;
int llr_offset;
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->llr = nrLDPC_TB_decoding_parameters->segments[r].llr;
rdata->Kc = decParams.BG == 2 ? 52 : 68;
rdata->C = nrLDPC_TB_decoding_parameters->C;
rdata->E = nrLDPC_TB_decoding_parameters->segments[r].E;
rdata->A = nrLDPC_TB_decoding_parameters->A;
rdata->Qm = nrLDPC_TB_decoding_parameters->Qm;
rdata->K = nrLDPC_TB_decoding_parameters->K;
......@@ -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->tbslbrm = nrLDPC_TB_decoding_parameters->tbslbrm;
rdata->abort_decode = nrLDPC_TB_decoding_parameters->abort_decode;
rdata->d = nrLDPC_TB_decoding_parameters->segments[r].d;
rdata->d_to_be_cleared = nrLDPC_TB_decoding_parameters->segments[r].d_to_be_cleared;
rdata->c = nrLDPC_TB_decoding_parameters->segments[r].c;
rdata->decodeSuccess = &nrLDPC_TB_decoding_parameters->segments[r].decodeSuccess;
rdata->p_ts_deinterleave = &nrLDPC_TB_decoding_parameters->segments[r].ts_deinterleave;
rdata->p_ts_rate_unmatch = &nrLDPC_TB_decoding_parameters->segments[r].ts_rate_unmatch;
rdata->p_ts_ldpc_decode = &nrLDPC_TB_decoding_parameters->segments[r].ts_ldpc_decode;
rdata->d = nrLDPC_TB_decoding_parameters->d + r * rdata->Kc * rdata->Z;
rdata->d_to_be_cleared = nrLDPC_TB_decoding_parameters->d_to_be_cleared;
rdata->c = nrLDPC_TB_decoding_parameters->c + r * (rdata->K >> 3);
AssertFatal(rdata->c != NULL,
"rdata->c is null, r %d, K %d, A %d, rv_index %d, TB_decoding_parameters->c %p\n",
r,
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};
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;
}
......@@ -284,12 +314,20 @@ int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_dec
// Execute thread pool tasks
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++) {
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++) {
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_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;
......
......@@ -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 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].c);
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
init_downlink_harq_status(harq_list[j] + i);
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].d = malloc16(a_segments*sizeof(int16_t *));
const int sz=5*8448*sizeof(int16_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(*harq_list[j][i].d) * 3 * 8448);
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].DLround = 0;
}
......
......@@ -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);
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->d);
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)
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));
harq->d = malloc16_clear(a_segments * sizeof(*harq->d));
for (int r = 0; r < a_segments; r++) {
harq->c[r] = malloc16_clear(8448 * sizeof(*harq->c[r]));
harq->d[r] = malloc16_clear(68 * 384 * sizeof(*harq->d[r]));
}
// Allocate one contiguous buffer fr all c/d arrays to simplify addressing for GPU LDPC offload
harq->c = malloc16_clear(a_segments * 8448 * sizeof(*harq->c));
harq->d = malloc16_clear(a_segments * 68 * 384 * sizeof(*harq->d));
harq->d_to_be_cleared = calloc(a_segments, sizeof(bool));
AssertFatal(harq->d_to_be_cleared != NULL, "out of memory\n");
return (ulsch);
......@@ -223,9 +216,6 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
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++) {
uint8_t ULSCH_id = ULSCH_ids[pusch_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,
}
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++) {
nrLDPC_segment_decoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
segment_parameters->E = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, TB_parameters->nb_layers, r);
segment_parameters->R = nr_get_R_ldpc_decoder(TB_parameters->rv_index,
segment_parameters->E,
TB_parameters->BG,
TB_parameters->Z,
&harq_process->llrLen,
harq_process->round);
segment_parameters->llr = ulsch_llr + r_offset;
segment_parameters->d = harq_process->d[r];
segment_parameters->d_to_be_cleared = &harq_process->d_to_be_cleared[r];
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;
int Etmp = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, TB_parameters->nb_layers, r);
if (TB_parameters->E != Etmp) {
TB_parameters->E2 = Etmp;
TB_parameters->R2 = nr_get_R_ldpc_decoder(TB_parameters->rv_index,
TB_parameters->E2,
TB_parameters->BG,
TB_parameters->Z,
&harq_process->llrLen,
harq_process->round);
TB_parameters->first_rE2 = r;
break;
}
harq_process->harq_to_be_cleared = false;
}
}
int ret_decoder = phy_vars_gNB->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters);
// post decode
for (uint8_t pusch_id = 0; pusch_id < nb_pusch; pusch_id++) {
uint8_t ULSCH_id = ULSCH_ids[pusch_id];
NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
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;
for (int r = 0; r < TB_parameters.C; r++) {
nrLDPC_segment_decoding_parameters_t nrLDPC_segment_decoding_parameters = TB_parameters.segments[r];
// Copy c to b in case of decoding success
if (nrLDPC_segment_decoding_parameters.decodeSuccess) {
uint32_t offset = 0, r_offset = 0;
bool crcok = true;
LOG_D(PHY, "C = %d\n", TB_parameters->C);
for (int r = 0; r < TB_parameters->C; r++) {
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,
harq_process->c[r],
harq_process->c + r_offset,
(harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
} else {
LOG_D(PHY, "uplink segment error %d/%d\n", r, harq_process->C);
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));
r_offset += (harq_process->K >> 3);
}
offset += ((harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
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);
} else {
LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
}
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;
......
......@@ -69,11 +69,11 @@ typedef struct {
NR_SCH_status_t status;
/// Pointer to the payload (38.212 V15.4.0 section 5.1)
uint8_t *b;
/// Pointers to transport block segments
uint8_t **c;
/// Pointer to transport block segments
uint8_t *c;
/// 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)
int16_t **d;
int16_t *d;
/// Index of current HARQ round for this DLSCH
uint8_t DLround;
/// Number of code segments
......
......@@ -133,16 +133,16 @@ typedef struct {
bool harq_to_be_cleared;
/// Pointer to the payload (38.212 V15.4.0 section 5.1)
uint8_t *b;
/// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2)
uint8_t **c;
/// Pointer to aggregated code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2)
uint8_t *c;
/// Number of bits in each code block (38.212 V15.4.0 section 5.2.2)
uint32_t K;
/// Number of "Filler" bits added in the code block segmentation (38.212 V15.4.0 section 5.2.2)
uint32_t F;
/// Number of code blocks after code block segmentation (38.212 V15.4.0 section 5.2.2)
uint32_t C;
/// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2)
int16_t **d;
/// Pointers to aggregated code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2)
int16_t *d;
/// 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
/// when true, clear d in the next call to function nr_rate_matching_ldpc_rx()
......
......@@ -16,6 +16,7 @@
FN(DLSCH_CHANNEL_ESTIMATION_STATS),\
FN(DLSCH_DECODING_STATS),\
FN(DLSCH_RATE_UNMATCHING_STATS),\
FN(DLSCH_SEG_PREP_STATS),\
FN(DLSCH_LDPC_DECODING_STATS),\
FN(DLSCH_DEINTERLEAVING_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