Commit a4718d4a authored by Cedric Roux's avatar Cedric Roux

bugfix: LDPC decoding in the gNB: clear d properly

The d array has to be cleared at the first usage, which may not necessarily
be when new_rx is true. For example, in case of DTX detected for a first
transmission, the next transmission won't have new_rx true, so d won't be
cleared, containing data from a previous transmission. Or when a LDPC
decoding is cancelled for a segment when new_rx is true, a decoding for
a retransmission will not clear d because then new_rx will not be true.
(Yes, the logic of cancellation will be changed in the future, but the
changes will be orthogonal to the ones of this commit.)

new_rx is removed.
parent da193d1b
...@@ -74,9 +74,11 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, ...@@ -74,9 +74,11 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB,
harq->slot=slot; harq->slot=slot;
harq->handled = 0; harq->handled = 0;
harq->status= NR_ACTIVE; 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); 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; harq->round = 0;
else else
harq->round++; harq->round++;
......
...@@ -77,6 +77,7 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr, uint16_t N_RB_UL) ...@@ -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]->c);
free_and_zero(ulsch->harq_processes[i]->d); free_and_zero(ulsch->harq_processes[i]->d);
free(ulsch->harq_processes[i]->d_to_be_cleared);
free_and_zero(ulsch->harq_processes[i]); free_and_zero(ulsch->harq_processes[i]);
ulsch->harq_processes[i] = NULL; 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) ...@@ -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]->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[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); return(ulsch);
...@@ -151,6 +154,7 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *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) /// 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]; //int16_t e[MAX_NUM_NR_ULSCH_SEGMENTS][3*8448];
ulsch->harq_processes[i]->E=0; ulsch->harq_processes[i]->E=0;
ulsch->harq_processes[i]->harq_to_be_cleared=true;
} }
} }
} }
...@@ -237,7 +241,7 @@ void nr_processULSegment(void* arg) { ...@@ -237,7 +241,7 @@ void nr_processULSegment(void* arg) {
harq_e, harq_e,
ulsch_harq->C, ulsch_harq->C,
rv_index, rv_index,
ulsch_harq->new_rx, ulsch_harq->d_to_be_cleared[r],
E, E,
ulsch_harq->F, ulsch_harq->F,
Kr-ulsch_harq->F-2*(p_decoderParms->Z))==-1) { Kr-ulsch_harq->F-2*(p_decoderParms->Z))==-1) {
...@@ -251,6 +255,8 @@ void nr_processULSegment(void* arg) { ...@@ -251,6 +255,8 @@ void nr_processULSegment(void* arg) {
stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats); 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); memset(ulsch_harq->c[r],0,Kr_bytes);
if (ulsch_harq->C == 1) { if (ulsch_harq->C == 1) {
...@@ -369,7 +375,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -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; 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", 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}; t_nrLDPC_dec_params decParams = {0};
decParams.BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph; decParams.BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph;
int kc; int kc;
...@@ -399,7 +405,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -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->power[aarx] = dB_fixed_x10(pusch->ulsch_power[aarx]);
stats->noise_power[aarx] = dB_fixed_x10(pusch->ulsch_noise_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_Qm = Qm;
stats->current_RI = n_layers; stats->current_RI = n_layers;
stats->total_bytes_tx += harq_process->TBS; stats->total_bytes_tx += harq_process->TBS;
...@@ -452,6 +458,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -452,6 +458,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
#ifdef DEBUG_ULSCH_DECODING #ifdef DEBUG_ULSCH_DECODING
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
#endif #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 = harq_process->K;
Kr_bytes = Kr >> 3; Kr_bytes = Kr >> 3;
...@@ -523,7 +536,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -523,7 +536,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
harq_e, harq_e,
harq_process->C, harq_process->C,
pusch_pdu->pusch_data.rv_index, pusch_pdu->pusch_data.rv_index,
harq_process->new_rx, harq_process->d_to_be_cleared[r],
E, E,
harq_process->F, harq_process->F,
Kr - harq_process->F - 2 * (decParams.Z)) Kr - harq_process->F - 2 * (decParams.Z))
...@@ -533,6 +546,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -533,6 +546,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
return 1; return 1;
} }
harq_process->d_to_be_cleared[r] = false;
// set first 2*Z_c bits to zeros // set first 2*Z_c bits to zeros
memset(&z[0], 0, 2 * harq_process->Z * sizeof(int16_t)); memset(&z[0], 0, 2 * harq_process->Z * sizeof(int16_t));
// set Filler bits // set Filler bits
......
...@@ -191,7 +191,9 @@ typedef struct { ...@@ -191,7 +191,9 @@ typedef struct {
uint32_t slot; uint32_t slot;
/// Index of current HARQ round for this DLSCH /// Index of current HARQ round for this DLSCH
uint8_t round; 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) /// Status Flag indicating for this ULSCH (idle,active,disabled)
NR_SCH_status_t status; 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 /// 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 { ...@@ -213,6 +215,10 @@ typedef struct {
uint32_t C; uint32_t C;
/// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2) /// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2)
int16_t **d; 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) /// LDPC lifting size (38.212 V15.4.0 table 5.3.2-1)
uint32_t Z; 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) /// Number of bits in each code block after rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
......
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