Commit b038ee0a authored by Cedric Roux's avatar Cedric Roux

NR LDPC processing: do not redo LDPC decoding on retransmission if not needed

Adding crc_ok[] so that we don't redo LDPC decoding of a segment on
retransmissions if the CRC was correct for the segment in a previous
transmission.

We have to be careful with DTX of round 0, because in this case
nr_ulsch_decoding() will never be called with new_rx == 1, so we
would not reset crc_ok[]. (Hopefully I understand things correctly
here...)
parent 7fc31d9c
......@@ -78,6 +78,7 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr, uint16_t N_RB_UL)
}
free_and_zero(ulsch->harq_processes[i]->c);
free_and_zero(ulsch->harq_processes[i]->d);
free_and_zero(ulsch->harq_processes[i]->crc_ok);
free_and_zero(ulsch->harq_processes[i]);
ulsch->harq_processes[i] = NULL;
}
......@@ -102,11 +103,13 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL)
ulsch = (NR_gNB_ULSCH_t *)malloc16_clear(sizeof(NR_gNB_ULSCH_t));
ulsch->max_ldpc_iterations = max_ldpc_iterations;
ulsch->a_segments = a_segments;
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
ulsch->harq_processes[i] = (NR_UL_gNB_HARQ_t *)malloc16_clear(sizeof(NR_UL_gNB_HARQ_t));
ulsch->harq_processes[i]->b = (uint8_t*)malloc16_clear(ulsch_bytes);
ulsch->harq_processes[i]->c = (uint8_t**)malloc16_clear(a_segments*sizeof(uint8_t *));
ulsch->harq_processes[i]->crc_ok = malloc16_clear(a_segments*sizeof(bool));
ulsch->harq_processes[i]->d = (int16_t**)malloc16_clear(a_segments*sizeof(int16_t *));
for (r=0; r<a_segments; r++) {
ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16_clear(8448*sizeof(uint8_t));
......@@ -165,6 +168,11 @@ 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;
if (ulsch_harq->crc_ok[rdata->segment_r]) {
LOG_D(PHY, "segment %d already decoded in a previous transmission, do nothing\n", rdata->segment_r);
rdata->decodeIterations = 0;
return;
}
t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms;
int length_dec;
int no_iteration_ldpc;
......@@ -311,6 +319,8 @@ void nr_processULSegment(void* arg) {
#endif
rdata->decodeIterations = no_iteration_ldpc;
if (rdata->decodeIterations > p_decoderParms->numMaxIter) rdata->decodeIterations--;
/* remember that the data is ok to not decode it again in case of retransmission */
ulsch_harq->crc_ok[r] = true;
} else {
#ifdef PRINT_CRC_CHECK
LOG_I(PHY,"CRC NOK\n");
......@@ -661,6 +671,9 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
rdata->ulsch = ulsch;
rdata->ulsch_id = ULSCH_id;
rdata->tbslbrm = pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes;
/* in case of a new rx, tell nr_processULSegment() to process the data, so set crc_ok[r] to false */
if (harq_process->new_rx)
harq_process->crc_ok[r] = false;
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);
......
......@@ -227,6 +227,8 @@ typedef struct {
uint32_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;
/// array to indicate that a segment has a valid CRC from a previous transmission to not run LDPC decoder again in a retransmission
bool *crc_ok;
/// 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)
......@@ -266,6 +268,8 @@ typedef struct {
uint8_t max_ldpc_iterations;
/// number of iterations used in last LDPC decoding
uint8_t last_iteration_cnt;
/// max number of segments for LDPC decoding
int a_segments;
} NR_gNB_ULSCH_t;
typedef struct {
......
......@@ -226,7 +226,6 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req, int *decodeSucces
memcpy(ulsch_harq->b+rdata->offset,
ulsch_harq->c[r],
rdata->Kr_bytes - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
} else {
LOG_D(PHY,"uplink segment error %d/%d\n",rdata->segment_r,rdata->nbSegments);
LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
......@@ -844,6 +843,14 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
Therefore, we don't yet call nr_fill_indication, it will be called later */
nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1);
pusch_DTX++;
/* if round == 0 we need to clear some data because nr_ulsch_decoding() won't do it for the retransmissions */
if (ulsch_harq->round == 0) {
int r;
LOG_D(PHY, "DTX for round 0, clear mandatory data\n");
for (r = 0; r < ulsch->a_segments; r++) {
ulsch_harq->crc_ok[r] = false;
}
}
continue;
}
} else {
......
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