diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c index 9b36197e45..c7bb47c581 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c @@ -218,7 +218,7 @@ static void nr_process_decode_segment(void *arg) int decodeIterations = LDPCdecoder(p_decoderParms, 0, 0, 0, l, llrProcBuf, p_procTime, rdata->abort_decode); - if (decodeIterations <= p_decoderParms->numMaxIter) { + if (decodeIterations < p_decoderParms->numMaxIter) { memcpy(rdata->c, llrProcBuf, K >> 3); *rdata->decodeSuccess = true; } else { diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c index 7960215ab7..b23db3781d 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c @@ -277,8 +277,8 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, int frame_rx, int s for (uint32_t job = 0; job < num_threads_prepare; job++) { args_fpga_decode_prepare_t *args = &arr[job]; - if (args->no_iteration_ldpc > TB_params->max_ldpc_iterations) - no_iteration_ldpc = TB_params->max_ldpc_iterations + 1; + if (args->no_iteration_ldpc >= TB_params->max_ldpc_iterations) + no_iteration_ldpc = TB_params->max_ldpc_iterations; } // launch decode with FPGA @@ -306,12 +306,12 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, int frame_rx, int s #ifdef DEBUG_CRC LOG_I(PHY, "segment %d CRC NOK\n", r); #endif - no_iteration_ldpc = TB_params->max_ldpc_iterations + 1; + no_iteration_ldpc = TB_params->max_ldpc_iterations; } for (int i = 0; i < out_CBoffset; i++) { segment_params->c[i] = multi_outdata[i + r * out_CBoffset]; } - segment_params->decodeSuccess = (no_iteration_ldpc <= TB_params->max_ldpc_iterations); + segment_params->decodeSuccess = (no_iteration_ldpc < TB_params->max_ldpc_iterations); if (segment_params->decodeSuccess) { *TB_params->processedSegments = *TB_params->processedSegments + 1; } @@ -396,7 +396,7 @@ void nr_ulsch_FPGA_decoding_prepare_blocks(void *args) == -1) { stop_meas(&segment_params->ts_rate_unmatch); LOG_E(PHY, "ulsch_decoding.c: Problem in rate_matching\n"); - no_iteration_ldpc = max_ldpc_iterations + 1; + no_iteration_ldpc = max_ldpc_iterations; arguments->no_iteration_ldpc = no_iteration_ldpc; return; } else { diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c index fcee71c151..e2ed7fce10 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c @@ -187,7 +187,7 @@ int32_t LDPCdecoder(t_nrLDPC_dec_params* p_decParams, // Launch LDPC decoder core for one segment int numIter = nrLDPC_decoder_core(p_llr, p_out, numLLR, p_lut, p_decParams, p_profiler, ab); - if (numIter > p_decParams->numMaxIter) { + if (numIter >= p_decParams->numMaxIter) { LOG_D(PHY, "set abort: %d, %d\n", numIter, p_decParams->numMaxIter); set_abort(ab, true); } @@ -549,13 +549,11 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, // estimated after only one iteration // First iteration finished - uint32_t numIter = 1; + uint32_t numIter = 0; int32_t pcRes = 1; // pcRes is 0 if the ldpc decoder is succesful - while ((numIter <= numMaxIter) && (pcRes != 0)) { - // Increase iteration counter - numIter++; + while ((numIter < numMaxIter) && (pcRes != 0)) { if (check_abort(ab)) { - numIter = numMaxIter + 2; + numIter = numMaxIter; break; } // CN processing @@ -847,7 +845,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, pcRes = nrLDPC_cnProcPc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z); NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->cnProcPc)); } else { - if (numIter > 2) { + if (numIter > 0) { int8_t llrOut[NR_LDPC_MAX_NUM_LLR] __attribute__((aligned(64))) = {0}; int8_t* p_llrOut = outMode == nrLDPC_outMode_LLRINT8 ? p_out : llrOut; nrLDPC_llrRes2llrOut(p_lut, p_llrOut, llrRes, Z, BG); @@ -861,6 +859,8 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, } } } + // Increase iteration counter + numIter++; } if (!p_decParams->check_crc) { int8_t llrOut[NR_LDPC_MAX_NUM_LLR] __attribute__((aligned(64))) = {0}; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index a3138f5d7f..e6b4503e1b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -59,14 +59,14 @@ void nr_dlsch_unscrambling(int16_t *llr, uint32_t size, uint8_t q, uint32_t Nid, /*! \brief Prepare necessary parameters for nrLDPC_coding_interface */ -uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, - const UE_nr_rxtx_proc_t *proc, - NR_UE_DLSCH_t *dlsch, - int16_t **dlsch_llr, - uint8_t **b, - int *G, - int nb_dlsch, - uint8_t *DLSCH_ids) +void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, + const UE_nr_rxtx_proc_t *proc, + NR_UE_DLSCH_t *dlsch, + int16_t **dlsch_llr, + uint8_t **b, + int *G, + int nb_dlsch, + uint8_t *DLSCH_ids) { nrLDPC_TB_decoding_parameters_t TBs[nb_dlsch]; memset(TBs, 0, sizeof(TBs)); @@ -100,7 +100,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if (!harq_process) { LOG_E(PHY, "dlsch_decoding_slot.c: NULL harq_process pointer\n"); - return dlsch[DLSCH_id].max_ldpc_iterations + 1; + return; } nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pdsch_id]; @@ -164,7 +164,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if (harq_process->C > MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * TB_parameters->nb_layers) { LOG_E(PHY, "nr_segmentation.c: too many segments %d, A %d\n", harq_process->C, TB_parameters->A); - return dlsch[DLSCH_id].max_ldpc_iterations + 1; + return; } if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD) && (!slot_parameters.frame % 100)) @@ -242,7 +242,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, int ret_decoder = phy_vars_ue->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters); if (ret_decoder != 0) { - return dlsch->max_ldpc_iterations + 1; + LOG_E(PHY, "nrLDPC_coding_decoder returned an error: %d\n", ret_decoder); + return; } // post decode @@ -316,11 +317,11 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if (harq_process->decodeResult) { LOG_D(PHY, "DLSCH received ok \n"); harq_process->status = SCH_IDLE; - dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations; + dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations - 1; } else { LOG_D(PHY, "DLSCH received nok \n"); kpiStructure.nb_nack++; - dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations + 1; + dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations; UEdumpScopeData(phy_vars_ue, proc->nr_slot_rx, proc->frame_rx, "DLSCH_NACK"); } @@ -355,5 +356,4 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, } - return dlsch[0].last_iteration_cnt; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 0ca616ba34..bb1a6c03df 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -81,14 +81,14 @@ void nr_conjch0_mult_ch1(int *ch0, @param[in] DLSCH_ids array of active downlink shared channels @returns 0 on success, 1 on unsuccessful decoding */ -uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, - const UE_nr_rxtx_proc_t *proc, - NR_UE_DLSCH_t *dlsch, - short **dlsch_llr, - uint8_t **b, - int *G, - int nb_dlsch, - uint8_t *DLSCH_ids); +void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, + const UE_nr_rxtx_proc_t *proc, + NR_UE_DLSCH_t *dlsch, + short **dlsch_llr, + uint8_t **b, + int *G, + int nb_dlsch, + uint8_t *DLSCH_ids); /** \brief This is the alternative top-level entry point for ULSCH encoding in UE. It handles all the HARQ processes in only one call. The routine first diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index 419988a961..07917b9075 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -147,7 +147,7 @@ typedef struct { /// Maximum number of LDPC iterations uint8_t max_ldpc_iterations; /// number of iterations used in last turbo decoding - uint8_t last_iteration_cnt; + int8_t last_iteration_cnt; /// bit mask of PT-RS ofdm symbol indicies uint16_t ptrs_symbols; // PTRS symbol index, to be updated every PTRS symbol within a slot. diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index eb0a1acc0e..47d41db44b 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -239,7 +239,7 @@ typedef struct { /// Maximum number of LDPC iterations uint8_t max_ldpc_iterations; /// number of iterations used in last LDPC decoding - uint8_t last_iteration_cnt; + int8_t last_iteration_cnt; /// Status Flag indicating for this ULSCH bool active; /// Flag to indicate that the UL configuration has been handled. Used to remove a stale ULSCH when frame wraps around diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 1484d44ddf..4f1f8ff010 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -424,7 +424,7 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, boo LOG_D(PHY, "ULSCH received ok \n"); ulsch->active = false; ulsch_harq->round = 0; - ulsch->last_iteration_cnt = ulsch->max_ldpc_iterations; // Setting to max_ldpc_iterations is sufficient given that this variable is only used for checking for failure + ulsch->last_iteration_cnt = ulsch->max_ldpc_iterations - 1; // Setting to max_ldpc_iterations - 1 is sufficient given that this variable is only used for checking for failure } else { LOG_D(PHY, "[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, ndi %d, status %d, round %d, RV %d, prb_start %d, prb_size %d, " @@ -444,7 +444,7 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, boo gNBdumpScopeData(gNB, ulsch->slot, ulsch->frame, "ULSCH_NACK"); ulsch->handled = 1; LOG_D(PHY, "ULSCH %d in error\n",ULSCH_id); - ulsch->last_iteration_cnt = ulsch->max_ldpc_iterations + 1; // Setting to max_ldpc_iterations + 1 is sufficient given that this variable is only used for checking for failure + ulsch->last_iteration_cnt = ulsch->max_ldpc_iterations; // Setting to max_ldpc_iterations is sufficient given that this variable is only used for checking for failure } } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index b57bf4eff3..283673a6df 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -686,20 +686,18 @@ static uint32_t compute_csi_rm_unav_res(fapi_nr_dl_config_dlsch_pdu_rel15_t *dls /*! \brief Process the whole DLSCH slot */ -static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, +static void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, NR_UE_DLSCH_t dlsch[2], int16_t *llr[2]) { if (dlsch[0].active == false) { LOG_E(PHY, "DLSCH should be active when calling this function\n"); - return true; + return; } - bool dec = false; int harq_pid = dlsch[0].dlsch_config.harq_process_nbr; int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; - uint32_t ret = UINT32_MAX; NR_DL_UE_HARQ_t *dl_harq0 = &ue->dl_harq_processes[0][harq_pid]; NR_DL_UE_HARQ_t *dl_harq1 = &ue->dl_harq_processes[1][harq_pid]; uint16_t dmrs_len = get_num_dmrs(dlsch[0].dlsch_config.dlDmrsSymbPos); @@ -732,7 +730,7 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, const int ack_nack_slot_and_frame = (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) + proc->frame_rx * ue->frame_parms.slots_per_frame; dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS]); - return false; + return; } int G[2]; @@ -765,11 +763,9 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, } start_meas_nr_ue_phy(ue, DLSCH_DECODING_STATS); - ret = nr_dlsch_decoding(ue, proc, dlsch, llr, p_b, G, nb_dlsch, DLSCH_ids); + nr_dlsch_decoding(ue, proc, dlsch, llr, p_b, G, nb_dlsch, DLSCH_ids); stop_meas_nr_ue_phy(ue, DLSCH_DECODING_STATS); - if (ret < ue->max_ldpc_iterations + 1) dec = true; - int ind_type = -1; switch (dlsch[0].rnti_type) { case TYPE_RA_RNTI_: @@ -829,7 +825,6 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, else if (ue->phy_sim_dlsch_b && is_cw1_active == ACTIVE) memcpy(ue->phy_sim_dlsch_b, p_b[1], dlsch_bytes); - return dec; } static bool is_ssb_index_transmitted(const PHY_VARS_NR_UE *ue, const int index) diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index de5c598015..977970c9f7 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -123,7 +123,6 @@ int main(int argc, char **argv) NR_DL_FRAME_PARMS *frame_parms; double sigma; unsigned char qbits = 8; - int ret; int loglvl = OAILOG_WARNING; uint8_t dlsch_threads = 0; float target_error_rate = 0.01; @@ -577,18 +576,18 @@ int main(int argc, char **argv) short *p_channel_output_fixed = channel_output_fixed; uint8_t *p_b = b; int available_bits_array[1] = { available_bits }; - ret = nr_dlsch_decoding(UE, - &proc, - dlsch0_ue, - &p_channel_output_fixed, - &p_b, - available_bits_array, - 1, - DLSCH_ids); + nr_dlsch_decoding(UE, + &proc, + dlsch0_ue, + &p_channel_output_fixed, + &p_b, + available_bits_array, + 1, + DLSCH_ids); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_OUT); - if (ret > dlsch0_ue->max_ldpc_iterations) + if (dlsch0_ue->last_iteration_cnt > dlsch0_ue->max_ldpc_iterations) n_errors++; //count errors diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 9014cd33ef..76c8881945 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -1163,7 +1163,7 @@ printf("%d\n", slot); //---------------------- count errors ---------------------- //---------------------------------------------------------- - if (dlsch0->last_iteration_cnt >= dlsch0->max_ldpc_iterations+1) + if (dlsch0->last_iteration_cnt >= dlsch0->max_ldpc_iterations) n_errors[round]++; int16_t *UE_llr = (int16_t*)UE->phy_sim_pdsch_llr; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index b45ca38254..4013951cab 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -1420,7 +1420,7 @@ int main(int argc, char *argv[]) 0); } - if ((ulsch_gNB->last_iteration_cnt >= ulsch_gNB->max_ldpc_iterations + 1) || ul_proc_error == 1) { + if ((ulsch_gNB->last_iteration_cnt >= ulsch_gNB->max_ldpc_iterations) || ul_proc_error == 1) { error_flag = 1; n_errors[round]++; crc_status = 1;