Commit 6d66049e authored by Cedric Roux's avatar Cedric Roux

NR LDPC processing: do not stop processing too early

It's important to feed data to the d[] array (and clear it first in case
of new_rx) so the logic to cancel the other LDPC processing threads when
a decoding failure happens has to be changed.

This commit introduces a new cancellation point possible only after
calling nr_rate_matching_ldpc_rx(), thus the d[] array receives data
for all the LDPC segments.
parent 1a0c0cd1
......@@ -252,6 +252,15 @@ void nr_processULSegment(void* arg) {
stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
}
/* don't run LDPC decoding if some other thread had a failure */
/* nr_rate_matching_ldpc_rx() must be called to feed d[r] in all cases
* so this test has to come after the call to nr_rate_matching_ldpc_rx()
*/
if (__atomic_load_n(&ulsch_harq->skip_ldpc_decoding, __ATOMIC_SEQ_CST)) {
LOG_D(PHY, "skipping nrLDPC_decoder() for r %d because decoding of some other segment failed\n", r);
return;
}
memset(ulsch_harq->c[r],0,Kr_bytes);
if (ulsch_harq->C == 1) {
......@@ -307,6 +316,8 @@ void nr_processULSegment(void* arg) {
LOG_I(PHY,"CRC NOK\n");
#endif
rdata->decodeIterations = max_ldpc_iterations + 1;
/* set skip_ldpc_decoding to 1 to indicate to remaining threads that they shall not run LDPC decoding */
__atomic_store_n(&ulsch_harq->skip_ldpc_decoding, 1, __ATOMIC_SEQ_CST);
}
for (int m=0; m < Kr>>3; m ++) {
......@@ -623,6 +634,9 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
else {
dtx_det = 0;
/* tell to the threads that LDPC decoding has to be done */
__atomic_store_n(&harq_process->skip_ldpc_decoding, 0, __ATOMIC_SEQ_CST);
for (int r = 0; r < harq_process->C; r++) {
int E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
union ldpcReqUnion id = {.s = {ulsch->rnti, frame, nr_tti_rx, 0, 0}};
......
......@@ -244,6 +244,11 @@ typedef struct {
/// Last index of LLR buffer that contains information.
/// Used for computing LDPC decoder R
int llrLen;
/// used to indicate to remaining threads that LDPC decoding has to be skipped
/// this is set to true when a crc fails to avoid unnecessary computation
/// all accesses must be done with __atomic operations
/// (we can't use bool, it does not work with __atomic operations)
uint8_t skip_ldpc_decoding;
//////////////////////////////////////////////////////////////
} NR_UL_gNB_HARQ_t;
......
......@@ -208,13 +208,15 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,0);
}
void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req, int *decodeSuccessCount) {
ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req);
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
NR_gNB_ULSCH_t *ulsch = rdata->ulsch;
int r = rdata->segment_r;
nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[rdata->ulsch_id]->harq_processes[rdata->harq_pid]->ulsch_pdu;
bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter);
if (decodeSuccess)
(*decodeSuccessCount)++;
ulsch_harq->processedSegments++;
LOG_D(PHY, "processing result of segment: %d, processed %d/%d\n",
rdata->segment_r, ulsch_harq->processedSegments, rdata->nbSegments);
......@@ -226,22 +228,14 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
rdata->Kr_bytes - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
} else {
if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
int nb = abortTpoolJob(&gNB->threadPool, req->key);
nb += abortNotifiedFIFOJob(&gNB->respDecode, req->key);
gNB->nbDecode-=nb;
LOG_D(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb);
LOG_D(PHY,"uplink segment error %d/%d\n",rdata->segment_r,rdata->nbSegments);
LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
ulsch_harq->processedSegments, nb, rdata->nbSegments);
ulsch_harq->processedSegments=rdata->nbSegments;
}
}
//int dumpsig=0;
// if all segments are done
if (rdata->nbSegments == ulsch_harq->processedSegments) {
if (decodeSuccess && !gNB->pusch_vars[rdata->ulsch_id]->DTX) {
if (*decodeSuccessCount == rdata->nbSegments && !gNB->pusch_vars[rdata->ulsch_id]->DTX) {
LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (pid %d, ndi %d, status %d, round %d, TBS %d, Max interation (all seg) %d)\n",
gNB->Mod_id,ulsch_harq->frame,ulsch_harq->slot,rdata->harq_pid,pusch_pdu->pusch_data.new_data_indicator,ulsch_harq->status,ulsch_harq->round,ulsch_harq->TBS,rdata->decodeIterations);
ulsch_harq->status = SCH_IDLE;
......@@ -379,11 +373,12 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
harq_pid,
G);
if (enable_ldpc_offload ==0) {
int decodeSuccessCount = 0;
while (gNB->nbDecode > 0) {
notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool);
if (req == NULL)
break; // Tpool has been stopped
nr_postDecode(gNB, req);
nr_postDecode(gNB, req, &decodeSuccessCount);
delNotifiedFIFO_elt(req);
}
}
......
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