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
......@@ -458,8 +458,9 @@ static int init_op_data_objs_dec(struct rte_bbdev_op_data *bufs,
bool large_input = false;
int j = 0;
for (int h = 0; h < nrLDPC_slot_decoding_parameters->nb_TBs; ++h) {
for (int i = 0; i < nrLDPC_slot_decoding_parameters->TBs[h].C; ++i) {
uint32_t data_len = nrLDPC_slot_decoding_parameters->TBs[h].segments[i].E;
nrLDPC_TB_decoding_parameters_t *p = &nrLDPC_slot_decoding_parameters->TBs[h];
for (int i = 0; i < p->C; ++i) {
uint32_t data_len = i < p->first_rE2 ? p->E : p->E2;
char *data;
struct rte_mbuf *m_head = rte_pktmbuf_alloc(mbuf_pool);
AssertFatal(m_head != NULL,
......@@ -602,20 +603,19 @@ static void set_ldpc_dec_op(struct rte_bbdev_dec_op **ops,
bool special_case_tb_mode = !active_dev.is_t2 && (nrLDPC_slot_decoding_parameters->nb_TBs == 1)
&& (nb_segments_decoding(nrLDPC_slot_decoding_parameters) == 1);
for (int h = 0; h < nrLDPC_slot_decoding_parameters->nb_TBs; ++h) {
for (int i = 0; i < nrLDPC_slot_decoding_parameters->TBs[h].C; ++i) {
ops[j]->ldpc_dec.basegraph = nrLDPC_slot_decoding_parameters->TBs[h].BG;
ops[j]->ldpc_dec.z_c = nrLDPC_slot_decoding_parameters->TBs[h].Z;
ops[j]->ldpc_dec.q_m = nrLDPC_slot_decoding_parameters->TBs[h].Qm;
ops[j]->ldpc_dec.n_filler = nrLDPC_slot_decoding_parameters->TBs[h].F;
ops[j]->ldpc_dec.n_cb = (nrLDPC_slot_decoding_parameters->TBs[h].BG == 1) ? (66 * nrLDPC_slot_decoding_parameters->TBs[h].Z)
: (50 * nrLDPC_slot_decoding_parameters->TBs[h].Z);
ops[j]->ldpc_dec.iter_max = nrLDPC_slot_decoding_parameters->TBs[h].max_ldpc_iterations;
ops[j]->ldpc_dec.rv_index = nrLDPC_slot_decoding_parameters->TBs[h].rv_index;
nrLDPC_TB_decoding_parameters_t *p = &nrLDPC_slot_decoding_parameters->TBs[h];
for (int i = 0; i < p->C; ++i) {
ops[j]->ldpc_dec.basegraph = p->BG;
ops[j]->ldpc_dec.z_c = p->Z;
ops[j]->ldpc_dec.q_m = p->Qm;
ops[j]->ldpc_dec.n_filler = p->F;
ops[j]->ldpc_dec.n_cb = (p->BG == 1) ? (66 * p->Z) : (50 * p->Z);
ops[j]->ldpc_dec.iter_max = p->max_ldpc_iterations;
ops[j]->ldpc_dec.rv_index = p->rv_index;
ops[j]->ldpc_dec.op_flags = RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE | RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE;
if (*nrLDPC_slot_decoding_parameters->TBs[h].segments[i].d_to_be_cleared) {
*nrLDPC_slot_decoding_parameters->TBs[h].segments[i].d_to_be_cleared = false;
if (p->d_to_be_cleared) {
if (active_dev.is_t2)
*nrLDPC_slot_decoding_parameters->TBs[h].processedSegments = 0;
*p->processedSegments = 0;
} else {
ops[j]->ldpc_dec.op_flags |= RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE;
if (active_dev.support_internal_harq_memory) {
......@@ -625,12 +625,12 @@ static void set_ldpc_dec_op(struct rte_bbdev_dec_op **ops,
}
if (!active_dev.is_t2)
*nrLDPC_slot_decoding_parameters->TBs[h].processedSegments = 0;
*p->processedSegments = 0;
if (!special_case_tb_mode) {
ops[j]->ldpc_dec.code_block_mode = 1;
ops[j]->ldpc_dec.cb_params.e = nrLDPC_slot_decoding_parameters->TBs[h].segments[i].E;
if (nrLDPC_slot_decoding_parameters->TBs[h].C > 1) {
ops[j]->ldpc_dec.cb_params.e = i < p->first_rE2 ? p->E : p->E2;
if (p->C > 1) {
ops[j]->ldpc_dec.op_flags |= RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP;
ops[j]->ldpc_dec.op_flags |= RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK;
}
......@@ -646,12 +646,12 @@ static void set_ldpc_dec_op(struct rte_bbdev_dec_op **ops,
ops[j]->ldpc_dec.tb_params.c = 1;
ops[j]->ldpc_dec.tb_params.r = 0;
ops[j]->ldpc_dec.tb_params.cab = 1;
ops[j]->ldpc_dec.tb_params.ea = nrLDPC_slot_decoding_parameters->TBs[h].segments[i].E;
ops[j]->ldpc_dec.tb_params.eb = nrLDPC_slot_decoding_parameters->TBs[h].segments[i].E;
ops[j]->ldpc_dec.tb_params.ea = i < p->first_rE2 ? p->E : p->E2;
ops[j]->ldpc_dec.tb_params.eb = i < p->first_rE2 ? p->E : p->E2;
}
// Calculate offset in the HARQ combined buffers
// Unique segment offset
uint32_t segment_offset = (nrLDPC_slot_decoding_parameters->TBs[h].harq_unique_pid * NR_LDPC_MAX_NUM_CB) + i;
uint32_t segment_offset = (p->harq_unique_pid * NR_LDPC_MAX_NUM_CB) + i;
// Prune to avoid shooting above maximum id
uint32_t pruned_segment_offset = segment_offset % active_dev.num_harq_codeblock;
// Segment offset to byte offset
......@@ -673,6 +673,7 @@ static void set_ldpc_dec_op(struct rte_bbdev_dec_op **ops,
ops[j]->ldpc_dec.input = inputs[j];
++j;
}
p->d_to_be_cleared = false;
}
}
......@@ -729,14 +730,16 @@ static int retrieve_ldpc_dec_op(struct rte_bbdev_dec_op **ops, nrLDPC_slot_decod
{
int j = 0;
for (int h = 0; h < nrLDPC_slot_decoding_parameters->nb_TBs; ++h) {
for (int i = 0; i < nrLDPC_slot_decoding_parameters->TBs[h].C; ++i) {
nrLDPC_TB_decoding_parameters_t *p = &nrLDPC_slot_decoding_parameters->TBs[h];
size_t data_off = 0;
for (int i = 0; i < p->C; ++i) {
struct rte_bbdev_op_data *hard_output = &ops[j]->ldpc_dec.hard_output;
struct rte_mbuf *m = hard_output->data;
uint16_t data_len = rte_pktmbuf_data_len(m) - hard_output->offset;
uint8_t *data = rte_pktmbuf_mtod_offset(m, uint8_t *, hard_output->offset);
memcpy(nrLDPC_slot_decoding_parameters->TBs[h].segments[i].c, data, data_len);
memcpy(p->c + data_off, data, data_len);
uint32_t segment_offset = (nrLDPC_slot_decoding_parameters->TBs[h].harq_unique_pid * NR_LDPC_MAX_NUM_CB) + i;
uint32_t segment_offset = (p->harq_unique_pid * NR_LDPC_MAX_NUM_CB) + i;
uint32_t pruned_segment_offset = segment_offset % active_dev.num_harq_codeblock;
struct rte_bbdev_op_data *harq_output = &ops[j]->ldpc_dec.harq_combined_output;
if (!active_dev.support_internal_harq_memory) {
......@@ -749,6 +752,7 @@ static int retrieve_ldpc_dec_op(struct rte_bbdev_dec_op **ops, nrLDPC_slot_decod
active_dev.harq_buffers[pruned_segment_offset].offset = harq_output->offset;
active_dev.harq_buffers[pruned_segment_offset].length = harq_output->length;
++j;
data_off += p->K >> 3;
}
}
return 0;
......@@ -823,7 +827,7 @@ static int pmd_lcore_ldpc_dec(void *arg)
// Start timer
// We report timing only once in (0,0) since the timers are merged at the end
start_meas(&nrLDPC_slot_decoding_parameters->TBs[0].segments[0].ts_ldpc_decode);
start_meas(&nrLDPC_slot_decoding_parameters->TBs[0].ts_ldpc_decode);
uint16_t enq = 0, deq = 0;
while (enq < num_segments) {
......@@ -840,7 +844,7 @@ static int pmd_lcore_ldpc_dec(void *arg)
// Stop timer
// We report timing only once in (0,0) since the timers are merged at the end
stop_meas(&nrLDPC_slot_decoding_parameters->TBs[0].segments[0].ts_ldpc_decode);
stop_meas(&nrLDPC_slot_decoding_parameters->TBs[0].ts_ldpc_decode);
if (deq == enq) {
ret = retrieve_ldpc_dec_op(ops_deq, nrLDPC_slot_decoding_parameters);
......@@ -849,24 +853,24 @@ static int pmd_lcore_ldpc_dec(void *arg)
/* get the max of iter_count for all dequeued ops */
int j = 0;
for (int h = 0; h < nrLDPC_slot_decoding_parameters->nb_TBs; ++h) {
for (int i = 0; i < nrLDPC_slot_decoding_parameters->TBs[h].C; ++i) {
bool *status = &nrLDPC_slot_decoding_parameters->TBs[h].segments[i].decodeSuccess;
nrLDPC_TB_decoding_parameters_t *p = &nrLDPC_slot_decoding_parameters->TBs[h];
for (int i = 0; i < p->C; ++i) {
bool *status = &p->decodeSuccess[i];
tp->iter_count = RTE_MAX(ops_enq[j]->ldpc_dec.iter_count, tp->iter_count);
// Check if CRC is available otherwise rely on ops_enq[j]->status to detect decoding success
// CRC is NOT available if the CRC type is 24_B which is when C is greater than 1
if (nrLDPC_slot_decoding_parameters->TBs[h].C > 1) {
if (p->C > 1) {
*status = (ops_enq[j]->status == 0);
} else {
uint8_t *decoded_bytes = nrLDPC_slot_decoding_parameters->TBs[h].segments[i].c;
uint8_t crc_type = crcType(nrLDPC_slot_decoding_parameters->TBs[h].C, nrLDPC_slot_decoding_parameters->TBs[h].A);
uint32_t len_with_crc = lenWithCrc(nrLDPC_slot_decoding_parameters->TBs[h].C, nrLDPC_slot_decoding_parameters->TBs[h].A);
uint8_t *decoded_bytes = p->c;
uint8_t crc_type = crcType(p->C, p->A);
uint32_t len_with_crc = lenWithCrc(p->C, p->A);
*status = check_crc(decoded_bytes, len_with_crc, crc_type);
}
if (*status) {
*nrLDPC_slot_decoding_parameters->TBs[h].processedSegments =
*nrLDPC_slot_decoding_parameters->TBs[h].processedSegments + 1;
*p->processedSegments = *p->processedSegments + 1;
}
++j;
}
......@@ -1283,28 +1287,24 @@ int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_dec
int8_t llr_decimal = (active_dev.info.drv.capabilities)[RTE_BBDEV_OP_LDPC_DEC].cap.ldpc_dec.llr_decimals;
int offset = 0;
for (int h = 0; h < nrLDPC_slot_decoding_parameters->nb_TBs; ++h) {
for (int r = 0; r < nrLDPC_slot_decoding_parameters->TBs[h].C; r++) {
nrLDPC_TB_decoding_parameters_t *p = &nrLDPC_slot_decoding_parameters->TBs[h];
size_t data_off = 0;
for (int r = 0; r < p->C; r++) {
uint32_t E = r < p->first_rE2 ? p->E : p->E2;
if (active_dev.is_t2) {
// For the T2, we simply saturate the LLRs.
uint16_t z_ol[LDPC_MAX_CB_SIZE] __attribute__((aligned(16)));
memcpy(z_ol,
nrLDPC_slot_decoding_parameters->TBs[h].segments[r].llr,
nrLDPC_slot_decoding_parameters->TBs[h].segments[r].E * sizeof(uint16_t));
memcpy(z_ol, p->llr + data_off, E * sizeof(uint16_t));
simde__m128i *pv_ol128 = (simde__m128i *)z_ol;
simde__m128i *pl_ol128 = (simde__m128i *)&l_ol[offset];
for (int i = 0, j = 0; j < ((nrLDPC_slot_decoding_parameters->TBs[h].segments[r].E + 15) >> 4); i += 2, j++) {
for (int i = 0, j = 0; j < ((E + 15) >> 4); i += 2, j++) {
pl_ol128[j] = simde_mm_packs_epi16(pv_ol128[i], pv_ol128[i + 1]);
}
} else {
llr_scaling(nrLDPC_slot_decoding_parameters->TBs[h].segments[r].llr,
nrLDPC_slot_decoding_parameters->TBs[h].segments[r].E,
&l_ol[offset],
llr_size,
llr_decimal,
nrLDPC_slot_decoding_parameters->TBs[h].nb_layers,
nrLDPC_slot_decoding_parameters->TBs[h].Qm);
llr_scaling(p->llr + data_off, E, &l_ol[offset], llr_size, llr_decimal, p->nb_layers, p->Qm);
}
offset += LDPC_MAX_CB_SIZE;
data_off += E;
}
}
......
......@@ -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;
......
......@@ -72,7 +72,7 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type);
uint8_t nb_re_dmrs;
LOG_D(PHY, "Round %d RV idx %d\n", harq_process->DLround, dlsch->dlsch_config.rv);
LOG_D(PHY, "Round %d RV idx %d\n", harq_process->DLround, dlsch_config->rv);
if (dmrs_Type == NFAPI_NR_DMRS_TYPE1)
nb_re_dmrs = 6 * dlsch_config->n_dmrs_cdm_groups;
......@@ -106,7 +106,7 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
TB_parameters->processedSegments = &harq_process->processedSegments;
float Coderate = (float)dlsch->dlsch_config.targetCodeRate / 10240.0f;
float Coderate = (float)dlsch_config->targetCodeRate / 10240.0f;
LOG_D(
PHY,
......@@ -150,8 +150,7 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD) && (!slot_parameters.frame % 100))
LOG_I(PHY, "K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, harq_process->Z, TB_parameters->nb_layers);
// clear HARQ buffer
for (int i = 0; i < harq_process->C; i++)
memset(harq_process->d[i], 0, 5 * 8448 * sizeof(int16_t));
memset(harq_process->d, 0, 3 * harq_process->K * harq_process->C * sizeof(int16_t));
} else {
// This is not a new packet, so retrieve previously computed quantities regarding segmentation
TB_parameters->C = harq_process->C;
......@@ -171,10 +170,7 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
set_abort(&harq_process->abort_decode, false);
}
nrLDPC_segment_decoding_parameters_t segments[nb_dlsch][max_num_segments];
memset(segments, 0, sizeof(segments));
bool d_to_be_cleared[nb_dlsch][max_num_segments];
memset(d_to_be_cleared, 0, sizeof(d_to_be_cleared));
bool d_to_be_cleared[nb_dlsch];
for (uint8_t pdsch_id = 0; pdsch_id < nb_dlsch; pdsch_id++) {
uint8_t DLSCH_id = DLSCH_ids[pdsch_id];
......@@ -183,37 +179,60 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
NR_DL_UE_HARQ_t *harq_process = &phy_vars_ue->dl_harq_processes[DLSCH_id][harq_pid];
nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pdsch_id];
TB_parameters->segments = segments[pdsch_id];
uint32_t r_offset = 0;
TB_parameters->llr = dlsch_llr[DLSCH_id];
LOG_D(NR_PHY,
"Decoding pdsch %d, C %d, Qm %d, TB_parameters->llr %p, DLSCH_id %d\n",
pdsch_id,
TB_parameters->C,
TB_parameters->Qm,
TB_parameters->llr,
DLSCH_id);
TB_parameters->c = harq_process->c;
TB_parameters->d = harq_process->d;
TB_parameters->E = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, TB_parameters->nb_layers, 0);
TB_parameters->E2 = TB_parameters->E;
TB_parameters->first_rE2 = TB_parameters->C;
for (int r = 1; r < TB_parameters->C; r++) {
int Er = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, TB_parameters->nb_layers, r);
if (Er != TB_parameters->E) {
TB_parameters->E2 = Er;
TB_parameters->first_rE2 = r;
break;
}
}
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->DLround);
if (harq_process->first_rx == 1)
d_to_be_cleared[pdsch_id] = true;
else
d_to_be_cleared[pdsch_id] = false;
TB_parameters->d_to_be_cleared = d_to_be_cleared[pdsch_id];
for (int r = 0; r < TB_parameters->C; r++)
TB_parameters->decodeSuccess[r] = false;
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++) {
if (harq_process->first_rx == 1)
d_to_be_cleared[pdsch_id][r] = true;
else
d_to_be_cleared[pdsch_id][r] = false;
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->DLround);
segment_parameters->llr = dlsch_llr[DLSCH_id] + r_offset;
segment_parameters->d = harq_process->d[r];
segment_parameters->d_to_be_cleared = &d_to_be_cleared[pdsch_id][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;
int Etmp = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, TB_parameters->nb_layers, r);
if (Etmp != TB_parameters->E) {
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->DLround);
TB_parameters->first_rE2 = r;
break;
}
}
}
......@@ -233,27 +252,45 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pdsch_id];
uint32_t offset = 0;
for (int r = 0; r < TB_parameters->C; r++) {
nrLDPC_segment_decoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
if (segment_parameters->decodeSuccess) {
uint32_t offset = 0, r_offset = 0;
bool crcok = true;
for (int r = 0; r < TB_parameters->C; r++)
if (TB_parameters->decodeSuccess[r] == false) {
crcok = false;
break;
}
if (crcok) {
for (int r = 0; r < TB_parameters->C; r++) {
memcpy(b[DLSCH_id] + 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 {
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[DLSCH_id].dlsch_config;
LOG_D(PHY, "frame=%d, slot=%d, first_rx=%d, rv_index=%d\n", proc->frame_rx, proc->nr_slot_rx, harq_process->first_rx, dlsch_config->rv);
LOG_D(PHY, "downlink segment error %d/%d\n", r, harq_process->C);
LOG_D(PHY, "DLSCH %d in error\n", DLSCH_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_ue->phy_cpu_stats.cpu_time_stats[DLSCH_DEINTERLEAVING_STATS], &segment_parameters->ts_deinterleave);
merge_meas(&phy_vars_ue->phy_cpu_stats.cpu_time_stats[DLSCH_RATE_UNMATCHING_STATS], &segment_parameters->ts_rate_unmatch);
merge_meas(&phy_vars_ue->phy_cpu_stats.cpu_time_stats[DLSCH_LDPC_DECODING_STATS], &segment_parameters->ts_ldpc_decode);
} else {
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[DLSCH_id].dlsch_config;
LOG_D(PHY,
"frame=%d, slot=%d, harq_pid %d, first_rx=%d, rv_index=%d, A %d, K %d, F %d, C %d,E %d,E2 %d,Qm %d\n",
proc->frame_rx,
proc->nr_slot_rx,
harq_pid,
harq_process->first_rx,
dlsch_config->rv,
TB_parameters->A,
harq_process->K,
harq_process->F,
harq_process->C,
TB_parameters->E,
TB_parameters->E2,
TB_parameters->Qm);
LOG_D(PHY, "DLSCH %d in error\n", DLSCH_id);
}
merge_meas(&phy_vars_ue->phy_cpu_stats.cpu_time_stats[DLSCH_DEINTERLEAVING_STATS], &TB_parameters->ts_deinterleave);
merge_meas(&phy_vars_ue->phy_cpu_stats.cpu_time_stats[DLSCH_RATE_UNMATCHING_STATS], &TB_parameters->ts_rate_unmatch);
merge_meas(&phy_vars_ue->phy_cpu_stats.cpu_time_stats[DLSCH_LDPC_DECODING_STATS], &TB_parameters->ts_ldpc_decode);
merge_meas(&phy_vars_ue->phy_cpu_stats.cpu_time_stats[DLSCH_SEG_PREP_STATS], &TB_parameters->ts_seg_prep);
kpiStructure.nb_total++;
kpiStructure.blockSize = dlsch_config->TBS;
kpiStructure.dl_mcs = dlsch_config->mcs;
......@@ -263,10 +300,10 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
if (harq_process->decodeResult && harq_process->C > 1) {
/* check global CRC */
int A = dlsch->dlsch_config.TBS;
int A = dlsch_config->TBS;
// we have regrouped the transport block
if (!check_crc(b[DLSCH_id], lenWithCrc(1, A), crcType(1, A))) {
LOG_E(PHY,
LOG_D(PHY,
" Frame %d.%d LDPC global CRC fails, but individual LDPC CRC succeeded. %d segs\n",
proc->frame_rx,
proc->nr_slot_rx,
......@@ -285,19 +322,25 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
i++;
if (i == sz) {
LOG_E(PHY,
"received all 0 pdu, consider it false reception, even if the TS 38.212 7.2.1 says only we should attach the "
"corresponding CRC, and nothing prevents to have a all 0 packet\n");
"received all 0 pdu (TBS %d, mcs %d, C %d, nb_rb %d, decodedSegments %d) consider it false reception, even if the "
"TS 38.212 7.2.1 says only we should attach the "
"corresponding CRC, and nothing prevents to have a all 0 packet\n",
dlsch_config->TBS,
dlsch_config->mcs,
harq_process->C,
dlsch->dlsch_config.number_rbs,
harq_process->processedSegments);
harq_process->decodeResult = false;
}
}
}
if (harq_process->decodeResult) {
LOG_D(PHY, "DLSCH received ok \n");
LOG_D(PHY, "%d.%d DLSCH received ok \n", proc->frame_rx, proc->nr_slot_rx);
harq_process->status = NR_SCH_IDLE;
dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations - 1;
} else {
LOG_D(PHY, "DLSCH received nok \n");
LOG_D(PHY, "%d.%d DLSCH received nok \n", proc->frame_rx, proc->nr_slot_rx);
kpiStructure.nb_nack++;
dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations;
UEdumpScopeData(phy_vars_ue, proc->nr_slot_rx, proc->frame_rx, "DLSCH_NACK");
......@@ -310,7 +353,7 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
else
nb_re_dmrs = 4 * dlsch_config->n_dmrs_cdm_groups;
uint16_t dmrs_length = get_num_dmrs(dlsch_config->dlDmrsSymbPos);
float Coderate = (float)dlsch->dlsch_config.targetCodeRate / 10240.0f;
float Coderate = (float)dlsch_config->targetCodeRate / 10240.0f;
LOG_D(PHY,
"%d.%d DLSCH Decoded, harq_pid %d, round %d, result: %d TBS %d (%d) G %d nb_re_dmrs %d length dmrs %d mcs %d Nl %d "
"nb_symb_sch %d "
......@@ -320,18 +363,17 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
harq_pid,
harq_process->DLround,
harq_process->decodeResult,
dlsch->dlsch_config.TBS,
dlsch->dlsch_config.TBS / 8,
dlsch_config->TBS,
dlsch_config->TBS / 8,
G[DLSCH_id],
nb_re_dmrs,
dmrs_length,
dlsch->dlsch_config.mcs,
dlsch_config->mcs,
dlsch->Nl,
dlsch_config->number_symbols,
number_rbs,
dlsch_config->qamModOrder,
Coderate);
}
}
......@@ -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