diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c index 9fb95ac273..d7098b4c8e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c @@ -74,9 +74,11 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, harq->slot=slot; harq->handled = 0; harq->status= NR_ACTIVE; - harq->new_rx = ulsch_pdu->pusch_data.new_data_indicator; + if (ulsch_pdu->pusch_data.new_data_indicator) + harq->harq_to_be_cleared = true; LOG_D(PHY,"ULSCH ID %d RNTI %x HARQ PID %d new data indicator %d\n",ulsch_id, ulsch_pdu->rnti, harq_pid, ulsch_pdu->pusch_data.new_data_indicator); - if (harq->new_rx) + + if (ulsch_pdu->pusch_data.new_data_indicator) harq->round = 0; else harq->round++; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 0bb872852b..3c6a16418e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -77,6 +77,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(ulsch->harq_processes[i]->d_to_be_cleared); free_and_zero(ulsch->harq_processes[i]); ulsch->harq_processes[i] = NULL; } @@ -111,6 +112,8 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL) ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16_clear(8448*sizeof(uint8_t)); ulsch->harq_processes[i]->d[r] = (int16_t*)malloc16_clear((68*384)*sizeof(int16_t)); } + ulsch->harq_processes[i]->d_to_be_cleared = calloc(a_segments, sizeof(bool)); + AssertFatal(ulsch->harq_processes[i]->d_to_be_cleared != NULL, "out of memory\n"); } return(ulsch); @@ -151,6 +154,7 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) //int16_t e[MAX_NUM_NR_ULSCH_SEGMENTS][3*8448]; ulsch->harq_processes[i]->E=0; + ulsch->harq_processes[i]->harq_to_be_cleared=true; } } } @@ -237,7 +241,7 @@ void nr_processULSegment(void* arg) { harq_e, ulsch_harq->C, rv_index, - ulsch_harq->new_rx, + ulsch_harq->d_to_be_cleared[r], E, ulsch_harq->F, Kr-ulsch_harq->F-2*(p_decoderParms->Z))==-1) { @@ -251,6 +255,8 @@ void nr_processULSegment(void* arg) { stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats); } + ulsch_harq->d_to_be_cleared[r] = false; + memset(ulsch_harq->c[r],0,Kr_bytes); if (ulsch_harq->C == 1) { @@ -369,7 +375,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, float Coderate = (float) pusch_pdu->target_code_rate / 10240.0f; LOG_D(PHY,"ULSCH Decoding, harq_pid %d rnti %x TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, Coderate %f RV %d round %d new RX %d\n", - harq_pid, ulsch->rnti, A, G, mcs, n_layers, nb_rb, Qm, Coderate, pusch_pdu->pusch_data.rv_index, harq_process->round, harq_process->new_rx); + harq_pid, ulsch->rnti, A, G, mcs, n_layers, nb_rb, Qm, Coderate, pusch_pdu->pusch_data.rv_index, harq_process->round, harq_process->harq_to_be_cleared); t_nrLDPC_dec_params decParams = {0}; decParams.BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph; int kc; @@ -399,7 +405,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, stats->power[aarx] = dB_fixed_x10(pusch->ulsch_power[aarx]); stats->noise_power[aarx] = dB_fixed_x10(pusch->ulsch_noise_power[aarx]); } - if (harq_process->new_rx == 0) { + if (!harq_process->harq_to_be_cleared) { stats->current_Qm = Qm; stats->current_RI = n_layers; stats->total_bytes_tx += harq_process->TBS; @@ -452,6 +458,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, #ifdef DEBUG_ULSCH_DECODING printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); #endif + + if (harq_process->harq_to_be_cleared) { + for (int r = 0; r < harq_process->C; r++) + harq_process->d_to_be_cleared[r] = true; + harq_process->harq_to_be_cleared = false; + } + Kr = harq_process->K; Kr_bytes = Kr >> 3; @@ -523,7 +536,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, harq_e, harq_process->C, pusch_pdu->pusch_data.rv_index, - harq_process->new_rx, + harq_process->d_to_be_cleared[r], E, harq_process->F, Kr - harq_process->F - 2 * (decParams.Z)) @@ -533,6 +546,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, return 1; } + harq_process->d_to_be_cleared[r] = false; + // set first 2*Z_c bits to zeros memset(&z[0], 0, 2 * harq_process->Z * sizeof(int16_t)); // set Filler bits diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 9c338b5d3f..8d8981c069 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -191,7 +191,9 @@ typedef struct { uint32_t slot; /// Index of current HARQ round for this DLSCH uint8_t round; - bool new_rx; + /// flag used to clear d properly (together with d_to_be_cleared below) + /// set to true in nr_fill_ulsch() when new_data_indicator is received + bool harq_to_be_cleared; /// Status Flag indicating for this ULSCH (idle,active,disabled) NR_SCH_status_t status; /// Flag to indicate that the UL configuration has been handled. Used to remove a stale ULSCH when frame wraps around @@ -213,6 +215,10 @@ typedef struct { uint32_t C; /// Pointers to 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() + bool *d_to_be_cleared; /// LDPC lifting size (38.212 V15.4.0 table 5.3.2-1) uint32_t Z; /// Number of bits in each code block after rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)