From 7cb8988372bc985c271ee700bcdef75c143f40e2 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 30 Aug 2023 10:52:56 +0200 Subject: [PATCH 1/2] one-step-cleaning-gNB-ulsch-decoding --- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 528 +++++++++--------- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 - 2 files changed, 261 insertions(+), 269 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 69015660d8..9d003b9ff5 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -125,34 +125,20 @@ static void nr_processULSegment(void *arg) PHY_VARS_gNB *phy_vars_gNB = rdata->gNB; NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq; t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms; - int length_dec; - int Kr; - int Kr_bytes; - int K_bits_F; - uint8_t crc_type; - int i; - int j; - int r = rdata->segment_r; - int A = rdata->A; - int E = rdata->E; - int Qm = rdata->Qm; - int rv_index = rdata->rv_index; - int r_offset = rdata->r_offset; - uint8_t kc = rdata->Kc; + const int Kr = ulsch_harq->K; + const int Kr_bytes = Kr >> 3; + const int K_bits_F = Kr - ulsch_harq->F; + const int r = rdata->segment_r; + const int A = rdata->A; + const int E = rdata->E; + const int Qm = rdata->Qm; + const int rv_index = rdata->rv_index; + const int r_offset = rdata->r_offset; + const uint8_t kc = rdata->Kc; short *ulsch_llr = rdata->ulsch_llr; - int max_ldpc_iterations = p_decoderParms->numMaxIter; + const int max_ldpc_iterations = p_decoderParms->numMaxIter; int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__((aligned(32))); - int16_t z[68 * 384 + 16] __attribute__((aligned(16))); - int8_t l[68 * 384 + 16] __attribute__((aligned(16))); - - simde__m128i *pv = (simde__m128i *)&z; - simde__m128i *pl = (simde__m128i *)&l; - - Kr = ulsch_harq->K; - Kr_bytes = Kr >> 3; - K_bits_F = Kr - ulsch_harq->F; - t_nrLDPC_time_stats procTime = {0}; t_nrLDPC_time_stats *p_procTime = &procTime; @@ -211,28 +197,33 @@ static void nr_processULSegment(void *arg) if (ulsch_harq->C == 1) { if (A > 3824) - crc_type = CRC24_A; + p_decoderParms->crc_type = CRC24_A; else - crc_type = CRC16; - - length_dec = ulsch_harq->B; + p_decoderParms->crc_type = CRC16; + p_decoderParms->block_length = ulsch_harq->B; } else { - crc_type = CRC24_B; - length_dec = (ulsch_harq->B + 24 * ulsch_harq->C) / ulsch_harq->C; + p_decoderParms->crc_type = CRC24_B; + p_decoderParms->block_length = (ulsch_harq->B + 24 * ulsch_harq->C) / ulsch_harq->C; } // start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats); // set first 2*Z_c bits to zeros - memset(&z[0], 0, 2 * ulsch_harq->Z * sizeof(int16_t)); + + int16_t z[68 * 384 + 16] __attribute__((aligned(16))); + + memset(z, 0, 2 * ulsch_harq->Z * sizeof(*z)); // set Filler bits - memset((&z[0] + K_bits_F), 127, ulsch_harq->F * sizeof(int16_t)); + memset(z + K_bits_F, 127, ulsch_harq->F * sizeof(*z)); // Move coded bits before filler bits - memcpy((&z[0] + 2 * ulsch_harq->Z), ulsch_harq->d[r], (K_bits_F - 2 * ulsch_harq->Z) * sizeof(int16_t)); + memcpy(z + 2 * ulsch_harq->Z, ulsch_harq->d[r], (K_bits_F - 2 * ulsch_harq->Z) * sizeof(*z)); // skip filler bits - memcpy((&z[0] + Kr), ulsch_harq->d[r] + (Kr - 2 * ulsch_harq->Z), (kc * ulsch_harq->Z - Kr) * sizeof(int16_t)); + memcpy(z + Kr, ulsch_harq->d[r] + (Kr - 2 * ulsch_harq->Z), (kc * ulsch_harq->Z - Kr) * sizeof(*z)); // Saturate coded bits before decoding into 8 bits values - for (i = 0, j = 0; j < ((kc * ulsch_harq->Z) >> 4) + 1; i += 2, j++) { + simde__m128i *pv = (simde__m128i *)&z; + int8_t l[68 * 384 + 16] __attribute__((aligned(16))); + simde__m128i *pl = (simde__m128i *)&l; + for (int i = 0, j = 0; j < ((kc * ulsch_harq->Z) >> 4) + 1; i += 2, j++) { pl[j] = simde_mm_packs_epi16(pv[i], pv[i + 1]); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -242,73 +233,194 @@ static void nr_processULSegment(void *arg) ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////// pl =====> llrProcBuf ////////////////////////////////// - p_decoderParms->block_length = length_dec; - p_decoderParms->crc_type = crc_type; - rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, (int8_t *)pl, llrProcBuf, p_procTime, &ulsch_harq->abort_decode); + rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, l, llrProcBuf, p_procTime, &ulsch_harq->abort_decode); if (rdata->decodeIterations <= p_decoderParms->numMaxIter) memcpy(ulsch_harq->c[r],llrProcBuf, Kr>>3); //stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats); } -int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, - uint8_t ULSCH_id, - short *ulsch_llr, - NR_DL_FRAME_PARMS *frame_parms, - nfapi_nr_pusch_pdu_t *pusch_pdu, - uint32_t frame, - uint8_t nr_tti_rx, - uint8_t harq_pid, - uint32_t G) - { - if (!ulsch_llr) { - LOG_E(PHY, "ulsch_decoding.c: NULL ulsch_llr pointer\n"); - return -1; - } +int decode_offload(PHY_VARS_gNB *phy_vars_gNB, + uint8_t ULSCH_id, + short *ulsch_llr, + nfapi_nr_pusch_pdu_t *pusch_pdu, + t_nrLDPC_dec_params *decParams, + uint8_t harq_pid, + uint32_t G) +{ + NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id]; + NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process; + int8_t llrProcBuf[22 * 384] __attribute__((aligned(32))); + int16_t z_ol[68 * 384] __attribute__((aligned(32))); + int8_t l_ol[68 * 384] __attribute__((aligned(32))); + int crc_type; + int length_dec; + uint8_t Qm = pusch_pdu->qam_mod_order; + uint8_t n_layers = pusch_pdu->nrOfLayers; + const int Kr = harq_process->K; + const int Kr_bytes = Kr >> 3; + const int kc = decParams->BG == 2 ? 52 : 68; + const uint32_t A = (harq_process->TBS) << 3; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 1); + if (harq_process->C == 1) { + if (A > 3824) + crc_type = CRC24_A; + else + crc_type = CRC16; - NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id]; - NR_gNB_PUSCH *pusch = &phy_vars_gNB->pusch_vars[ULSCH_id]; - NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process; - - if (!harq_process) { - LOG_E(PHY, "ulsch_decoding.c: NULL harq_process pointer\n"); - return -1; + length_dec = harq_process->B; + } else { + crc_type = CRC24_B; + length_dec = (harq_process->B + 24 * harq_process->C) / harq_process->C; } - uint8_t dtx_det = 0; + int decodeIterations = 2; + int dtx_det = 0; + int r_offset = 0, offset = 0; + for (int r = 0; r < harq_process->C; r++) { + int E = nr_get_E(G, harq_process->C, Qm, n_layers, r); + memset(harq_process->c[r], 0, Kr_bytes); - int Kr; - int Kr_bytes; + decParams->R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index, + E, + decParams->BG, + decParams->Z, + &harq_process->llrLen, + harq_process->round); + + if ((dtx_det == 0) && (pusch_pdu->pusch_data.rv_index == 0)) { + memcpy(z_ol, ulsch_llr + r_offset, E * sizeof(short)); + simde__m128i *pv_ol128 = (simde__m128i *)&z_ol; + simde__m128i *pl_ol128 = (simde__m128i *)&l_ol; + for (int i = 0, j = 0; j < ((kc * harq_process->Z) >> 4) + 1; i += 2, j++) { + pl_ol128[j] = simde_mm_packs_epi16(pv_ol128[i], pv_ol128[i + 1]); + } + + int ret = nrLDPC_decoder_offload(decParams, + harq_pid, + ULSCH_id, + r, + pusch_pdu->pusch_data.rv_index, + harq_process->F, + E, + Qm, + (int8_t *)&pl_ol128[0], + llrProcBuf, + 1); + if (ret < 0) { + LOG_E(PHY, "ulsch_decoding.c: Problem in LDPC decoder offload\n"); + + decodeIterations = ulsch->max_ldpc_iterations + 1; + return -1; + } + for (int m = 0; m < Kr >> 3; m++) { + harq_process->c[r][m] = (uint8_t)llrProcBuf[m]; + } + + if (check_crc((uint8_t *)llrProcBuf, length_dec, crc_type)) { + PRINT_CRC_CHECK(LOG_I(PHY, "Segment %d CRC OK\n", r)); + decodeIterations = 2; + } else { + PRINT_CRC_CHECK(LOG_I(PHY, "segment %d CRC NOK\n", r)); + decodeIterations = ulsch->max_ldpc_iterations + 1; + } + //} + + r_offset += E; + + /*for (int k=0;k<8;k++) + { + printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); + printf("llrprocbuf [%d] = %x adr %p\n", k, llrProcBuf[k], llrProcBuf+k); + } + */ + } else { + dtx_det = 0; + decodeIterations = ulsch->max_ldpc_iterations + 1; + } + bool decodeSuccess = (decodeIterations <= ulsch->max_ldpc_iterations); + if (decodeSuccess) { + memcpy(harq_process->b + offset, harq_process->c[r], Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); + offset += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); + harq_process->processedSegments++; + } else { + LOG_D(PHY, "uplink segment error %d/%d\n", r, harq_process->C); + LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id); + break; // don't even attempt to decode other segments + } + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 0); + + if (harq_process->processedSegments == harq_process->C) { + LOG_D(PHY, "ULSCH: Setting ACK for slot %d TBS %d\n", ulsch->slot, harq_process->TBS); + ulsch->active = false; + harq_process->round = 0; + + LOG_D(PHY, "ULSCH received ok \n"); + nr_fill_indication(phy_vars_gNB, ulsch->frame, ulsch->slot, ULSCH_id, harq_pid, 0, 0); + + } else { + LOG_D(PHY, + "[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d)\n", + phy_vars_gNB->Mod_id, + ulsch->frame, + ulsch->slot, + harq_pid, + ulsch->active, + harq_process->round, + harq_process->TBS); + ulsch->handled = 1; + decodeIterations = ulsch->max_ldpc_iterations + 1; + LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id); + nr_fill_indication(phy_vars_gNB, ulsch->frame, ulsch->slot, ULSCH_id, harq_pid, 1, 0); + } + ulsch->last_iteration_cnt = decodeIterations; + return 0; +} + +int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, + uint8_t ULSCH_id, + short *ulsch_llr, + NR_DL_FRAME_PARMS *frame_parms, + nfapi_nr_pusch_pdu_t *pusch_pdu, + uint32_t frame, + uint8_t nr_tti_rx, + uint8_t harq_pid, + uint32_t G) +{ + if (!ulsch_llr) { + LOG_E(PHY, "ulsch_decoding.c: NULL ulsch_llr pointer\n"); + return -1; + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 1); + + NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id]; + NR_gNB_PUSCH *pusch = &phy_vars_gNB->pusch_vars[ULSCH_id]; + NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process; + + if (!harq_process) { + LOG_E(PHY, "ulsch_decoding.c: NULL harq_process pointer\n"); + return -1; + } + + // ------------------------------------------------------------------ + const uint16_t nb_rb = pusch_pdu->rb_size; + const uint8_t Qm = pusch_pdu->qam_mod_order; + const uint8_t mcs = pusch_pdu->mcs_index; + const uint8_t n_layers = pusch_pdu->nrOfLayers; + // ------------------------------------------------------------------ harq_process->processedSegments = 0; - - // ------------------------------------------------------------------ - uint16_t nb_rb = pusch_pdu->rb_size; - uint8_t Qm = pusch_pdu->qam_mod_order; - uint8_t mcs = pusch_pdu->mcs_index; - uint8_t n_layers = pusch_pdu->nrOfLayers; - // ------------------------------------------------------------------ - harq_process->TBS = pusch_pdu->pusch_data.tb_size; - dtx_det = 0; - - uint32_t A = (harq_process->TBS) << 3; - - // target_code_rate is in 0.1 units - 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->harq_to_be_cleared); t_nrLDPC_dec_params decParams = {0}; decParams.BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph; - int kc; - if (decParams.BG == 2) { - kc = 52; - } else { - kc = 68; - } + const uint32_t A = (harq_process->TBS) << 3; + if (A > 3824) + harq_process->B = A + 24; + else + harq_process->B = A + 16; NR_gNB_PHY_STATS_t *stats = get_phy_stats(phy_vars_gNB, ulsch->rnti); if (stats) { @@ -324,10 +436,21 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, stats->ulsch_stats.total_bytes_tx += harq_process->TBS; } } - if (A > 3824) - harq_process->B = A+24; - else - harq_process->B = A+16; + + 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, + pusch_pdu->target_code_rate / 10240.0f, + pusch_pdu->pusch_data.rv_index, + harq_process->round, + harq_process->harq_to_be_cleared); // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F) nr_segmentation(NULL, @@ -339,204 +462,75 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, &harq_process->F, decParams.BG); - if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*n_layers) { + uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * n_layers; // number of segments to be allocated + if (harq_process->C > a_segments) { LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",harq_process->C,harq_process->B); return(-1); } - - -#ifdef DEBUG_ULSCH_DECODING - printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z); - if (!frame%100) - printf("K %d C %d Z %d \n", harq_process->K, harq_process->C, harq_process->Z); -#endif - decParams.Z = harq_process->Z; - - decParams.numMaxIter = ulsch->max_ldpc_iterations; - decParams.outMode = 0; - - uint32_t r_offset = 0; - - uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*n_layers; //number of segments to be allocated - if (nb_rb != 273) { a_segments = a_segments*nb_rb; a_segments = a_segments/273 +1; } - if (harq_process->C > a_segments) { LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments); return -1; } + #ifdef DEBUG_ULSCH_DECODING + printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z); + if (!frame % 100) + printf("K %d C %d Z %d \n", harq_process->K, harq_process->C, harq_process->Z); printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); #endif + decParams.Z = harq_process->Z; + decParams.numMaxIter = ulsch->max_ldpc_iterations; + decParams.outMode = 0; + 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; + if (phy_vars_gNB->ldpc_offload_flag && mcs > 9) + return decode_offload(phy_vars_gNB, ULSCH_id, ulsch_llr, pusch_pdu, &decParams, harq_pid, G); - uint32_t offset = 0; - if (phy_vars_gNB->ldpc_offload_flag && mcs > 9) { - int8_t llrProcBuf[22 * 384]; - // if (dtx_det==0) { - int16_t z_ol[68 * 384]; - int8_t l_ol[68 * 384]; - int crc_type; - int length_dec; - - if (harq_process->C == 1) { - if (A > 3824) - crc_type = CRC24_A; - else - crc_type = CRC16; - - length_dec = harq_process->B; - } else { - crc_type = CRC24_B; - length_dec = (harq_process->B + 24 * harq_process->C) / harq_process->C; - } - int decodeIterations = 2; - for (int r = 0; r < harq_process->C; r++) { - int E = nr_get_E(G, harq_process->C, Qm, n_layers, r); - memset(harq_process->c[r], 0, Kr_bytes); - - decParams.R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index, E, decParams.BG, decParams.Z, &harq_process->llrLen, harq_process->round); - - if ((dtx_det == 0) && (pusch_pdu->pusch_data.rv_index == 0)) { - // if (dtx_det==0){ - memcpy((&z_ol[0]), ulsch_llr + r_offset, E * sizeof(short)); - simde__m128i *pv_ol128 = (simde__m128i *)&z_ol; - simde__m128i *pl_ol128 = (simde__m128i *)&l_ol; - for (int i = 0, j = 0; j < ((kc * harq_process->Z) >> 4) + 1; i += 2, j++) { - pl_ol128[j] = simde_mm_packs_epi16(pv_ol128[i], pv_ol128[i + 1]); - } - - int ret = nrLDPC_decoder_offload(&decParams, harq_pid, ULSCH_id, r, pusch_pdu->pusch_data.rv_index, harq_process->F, E, Qm, (int8_t *)&pl_ol128[0], llrProcBuf, 1); - if (ret < 0) { - LOG_E(PHY, "ulsch_decoding.c: Problem in LDPC decoder offload\n"); - - decodeIterations = ulsch->max_ldpc_iterations + 1; - return -1; - } - for (int m = 0; m < Kr >> 3; m++) { - harq_process->c[r][m] = (uint8_t)llrProcBuf[m]; - } - - if (check_crc((uint8_t *)llrProcBuf, length_dec, crc_type)) { - PRINT_CRC_CHECK(LOG_I(PHY, "Segment %d CRC OK\n", r)); - decodeIterations = 2; - } else { - PRINT_CRC_CHECK(LOG_I(PHY, "segment %d CRC NOK\n", r)); - decodeIterations = ulsch->max_ldpc_iterations + 1; - } - //} - - r_offset += E; - - /*for (int k=0;k<8;k++) - { - printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); - printf("llrprocbuf [%d] = %x adr %p\n", k, llrProcBuf[k], llrProcBuf+k); - } - */ - } else { - dtx_det = 0; - decodeIterations = ulsch->max_ldpc_iterations + 1; - } - bool decodeSuccess = (decodeIterations <= ulsch->max_ldpc_iterations); - if (decodeSuccess) { - memcpy(harq_process->b + offset, harq_process->c[r], Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); - offset += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); - harq_process->processedSegments++; - } else { - LOG_D(PHY, "uplink segment error %d/%d\n", r, harq_process->C); - LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id); - break; // don't even attempt to decode other segments - } - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 0); - - bool crc_valid = false; - if (harq_process->processedSegments == harq_process->C) { - // When the number of code blocks is 1 (C = 1) and ulsch_harq->processedSegments = 1, we can assume a good TB because of the - // CRC check made by the LDPC for early termination, so, no need to perform CRC check twice for a single code block - crc_valid = true; - if (harq_process->C > 1) { - // Check ULSCH transport block CRC - crc_type = CRC16; - if (A > 3824) { - crc_type = CRC24_A; - } - crc_valid = check_crc(harq_process->b, harq_process->B, crc_type); - } - } - - if (crc_valid) { - LOG_D(PHY, "[gNB %d] ULSCH: Setting ACK for slot %d TBS %d\n", phy_vars_gNB->Mod_id, ulsch->slot, harq_process->TBS); - ulsch->active = false; - harq_process->round = 0; - - LOG_D(PHY, "ULSCH received ok \n"); - nr_fill_indication(phy_vars_gNB, ulsch->frame, ulsch->slot, ULSCH_id, harq_pid, 0, 0); - - } else { - LOG_D(PHY, - "[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d)\n", - phy_vars_gNB->Mod_id, - ulsch->frame, - ulsch->slot, - harq_pid, - ulsch->active, - harq_process->round, - harq_process->TBS); - ulsch->handled = 1; - decodeIterations = ulsch->max_ldpc_iterations + 1; - LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id); - nr_fill_indication(phy_vars_gNB, ulsch->frame, ulsch->slot, ULSCH_id, harq_pid, 1, 0); - } - ulsch->last_iteration_cnt = decodeIterations; - } - - else { - dtx_det = 0; - set_abort(&harq_process->abort_decode, false); - 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}}; - notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(ldpcDecode_t), id.p, &phy_vars_gNB->respDecode, &nr_processULSegment); - ldpcDecode_t *rdata = (ldpcDecode_t *)NotifiedFifoData(req); - decParams.R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index, E, decParams.BG, decParams.Z, &harq_process->llrLen, harq_process->round); - rdata->gNB = phy_vars_gNB; - rdata->ulsch_harq = harq_process; - rdata->decoderParms = decParams; - rdata->ulsch_llr = ulsch_llr; - rdata->Kc = kc; - rdata->harq_pid = harq_pid; - rdata->segment_r = r; - rdata->nbSegments = harq_process->C; - rdata->E = E; - rdata->A = A; - rdata->Qm = Qm; - rdata->r_offset = r_offset; - rdata->Kr_bytes = Kr_bytes; - rdata->rv_index = pusch_pdu->pusch_data.rv_index; - rdata->offset = offset; - rdata->ulsch = ulsch; - rdata->ulsch_id = ULSCH_id; - rdata->tbslbrm = pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes; - pushTpool(&phy_vars_gNB->threadPool, req); - LOG_D(PHY, "Added a block to decode, in pipe: %d\n", r); - r_offset += E; - offset += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); - ////////////////////////////////////////////////////////////////////////////////////////// - } + uint32_t offset = 0, r_offset = 0; + set_abort(&harq_process->abort_decode, false); + 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}}; + notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(ldpcDecode_t), id.p, &phy_vars_gNB->respDecode, &nr_processULSegment); + ldpcDecode_t *rdata = (ldpcDecode_t *)NotifiedFifoData(req); + decParams.R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index, + E, + decParams.BG, + decParams.Z, + &harq_process->llrLen, + harq_process->round); + rdata->gNB = phy_vars_gNB; + rdata->ulsch_harq = harq_process; + rdata->decoderParms = decParams; + rdata->ulsch_llr = ulsch_llr; + rdata->Kc = decParams.BG == 2 ? 52 : 68; + rdata->harq_pid = harq_pid; + rdata->segment_r = r; + rdata->nbSegments = harq_process->C; + rdata->E = E; + rdata->A = A; + rdata->Qm = Qm; + rdata->r_offset = r_offset; + rdata->Kr_bytes = harq_process->K >> 3; + rdata->rv_index = pusch_pdu->pusch_data.rv_index; + rdata->offset = offset; + rdata->ulsch = ulsch; + rdata->ulsch_id = ULSCH_id; + rdata->tbslbrm = pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes; + pushTpool(&phy_vars_gNB->threadPool, req); + LOG_D(PHY, "Added a block to decode, in pipe: %d\n", r); + r_offset += E; + offset += ((harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); } return harq_process->C; } diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 184e3ec63b..6ad14f1836 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -953,7 +953,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX, 0); } } - if (totalDecode > 0 && gNB->ldpc_offload_flag == 0) { while (totalDecode > 0) { notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool); if (req == NULL) @@ -962,7 +961,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) delNotifiedFIFO_elt(req); totalDecode--; } - } for (int i = 0; i < gNB->max_nb_srs; i++) { NR_gNB_SRS_t *srs = &gNB->srs[i]; if (srs) { From d448b5e54974b8898863fa6a91adf87e312aaf86 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 27 Sep 2023 10:31:00 +0200 Subject: [PATCH 2/2] remove 'B' from persisted data, replace 3824 hardcoded by it's existing define --- CMakeLists.txt | 1 + openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 11 ++-- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 49 +++-------------- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 52 +++++-------------- .../PHY/NR_UE_TRANSPORT/nr_transport_ue.h | 4 -- .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 36 ++++++------- openair1/PHY/defs_gNB.h | 16 ++++-- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 7 +-- .../NR_MAC_COMMON/nr_compute_tbs_common.c | 8 +-- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 3 +- 10 files changed, 61 insertions(+), 126 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec60df8b35..08a75e378e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1144,6 +1144,7 @@ add_library(PHY_NR_COMMON ${PHY_NR_SRC_COMMON}) add_library(PHY_NR ${PHY_NR_SRC}) add_library(PHY_NR_UE ${PHY_NR_UE_SRC}) +target_link_libraries(PHY_NR_UE PRIVATE asn1_nr_rrc_hdrs) add_library(PHY_RU ${PHY_SRC_RU}) target_link_libraries(PHY_RU PRIVATE asn1_lte_rrc_hdrs) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index d244881c32..5f5a9260cd 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -297,7 +297,8 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, } int max_bytes = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*rel15->nrOfLayers*1056; - if (A > 3824) { + int B; + if (A > NR_MAX_PDSCH_TBS) { // Add 24-bit crc (polynomial A) to payload crc = crc24a(a,A)>>8; a[A>>3] = ((uint8_t *)&crc)[2]; @@ -305,7 +306,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, a[2+(A>>3)] = ((uint8_t *)&crc)[0]; //printf("CRC %x (A %d)\n",crc,A); //printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]); - harq->B = A+24; + B = A + 24; // harq->b = a; AssertFatal((A / 8) + 4 <= max_bytes, "A %d is too big (A/8+4 = %d > %d)\n", @@ -320,7 +321,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, a[1+(A>>3)] = ((uint8_t *)&crc)[0]; //printf("CRC %x (A %d)\n",crc,A); //printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]); - harq->B = A+16; + B = A + 16; // harq->b = a; AssertFatal((A / 8) + 3 <= max_bytes, "A %d is too big (A/8+3 = %d > %d)\n", @@ -333,11 +334,11 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, impp.BG = rel15->maintenance_parms_v3.ldpcBaseGraph; start_meas(dlsch_segmentation_stats); - impp.Kb = nr_segmentation(harq->b, harq->c, harq->B, &impp.n_segments, &impp.K, impp.Zc, &impp.F, impp.BG); + impp.Kb = nr_segmentation(harq->b, harq->c, B, &impp.n_segments, &impp.K, impp.Zc, &impp.F, impp.BG); stop_meas(dlsch_segmentation_stats); if (impp.n_segments>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*rel15->nrOfLayers) { - LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",impp.n_segments,harq->B); + LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", impp.n_segments, B); return(-1); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 9d003b9ff5..01d428038c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -194,18 +194,8 @@ static void nr_processULSegment(void *arg) ulsch_harq->d_to_be_cleared[r] = false; memset(ulsch_harq->c[r], 0, Kr_bytes); - - if (ulsch_harq->C == 1) { - if (A > 3824) - p_decoderParms->crc_type = CRC24_A; - else - p_decoderParms->crc_type = CRC16; - p_decoderParms->block_length = ulsch_harq->B; - } else { - p_decoderParms->crc_type = CRC24_B; - p_decoderParms->block_length = (ulsch_harq->B + 24 * ulsch_harq->C) / ulsch_harq->C; - } - + p_decoderParms->crc_type = crcType(ulsch_harq->C, A); + p_decoderParms->block_length = lenWithCrc(ulsch_harq->C, A); // start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats); // set first 2*Z_c bits to zeros @@ -253,26 +243,12 @@ int decode_offload(PHY_VARS_gNB *phy_vars_gNB, int8_t llrProcBuf[22 * 384] __attribute__((aligned(32))); int16_t z_ol[68 * 384] __attribute__((aligned(32))); int8_t l_ol[68 * 384] __attribute__((aligned(32))); - int crc_type; - int length_dec; uint8_t Qm = pusch_pdu->qam_mod_order; uint8_t n_layers = pusch_pdu->nrOfLayers; const int Kr = harq_process->K; const int Kr_bytes = Kr >> 3; const int kc = decParams->BG == 2 ? 52 : 68; const uint32_t A = (harq_process->TBS) << 3; - - if (harq_process->C == 1) { - if (A > 3824) - crc_type = CRC24_A; - else - crc_type = CRC16; - - length_dec = harq_process->B; - } else { - crc_type = CRC24_B; - length_dec = (harq_process->B + 24 * harq_process->C) / harq_process->C; - } int decodeIterations = 2; int dtx_det = 0; int r_offset = 0, offset = 0; @@ -316,23 +292,15 @@ int decode_offload(PHY_VARS_gNB *phy_vars_gNB, harq_process->c[r][m] = (uint8_t)llrProcBuf[m]; } - if (check_crc((uint8_t *)llrProcBuf, length_dec, crc_type)) { + if (check_crc((uint8_t *)llrProcBuf, lenWithCrc(harq_process->C, A), crcType(harq_process->C, A))) { PRINT_CRC_CHECK(LOG_I(PHY, "Segment %d CRC OK\n", r)); decodeIterations = 2; } else { PRINT_CRC_CHECK(LOG_I(PHY, "segment %d CRC NOK\n", r)); decodeIterations = ulsch->max_ldpc_iterations + 1; } - //} r_offset += E; - - /*for (int k=0;k<8;k++) - { - printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); - printf("llrprocbuf [%d] = %x adr %p\n", k, llrProcBuf[k], llrProcBuf+k); - } - */ } else { dtx_det = 0; decodeIterations = ulsch->max_ldpc_iterations + 1; @@ -417,11 +385,6 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, t_nrLDPC_dec_params decParams = {0}; decParams.BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph; const uint32_t A = (harq_process->TBS) << 3; - if (A > 3824) - harq_process->B = A + 24; - else - harq_process->B = A + 16; - NR_gNB_PHY_STATS_t *stats = get_phy_stats(phy_vars_gNB, ulsch->rnti); if (stats) { stats->frame = frame; @@ -452,10 +415,10 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, harq_process->round, harq_process->harq_to_be_cleared); - // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F) + // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (C, K, Z, F) nr_segmentation(NULL, NULL, - harq_process->B, + lenWithCrc(1, A), // size in case of 1 segment &harq_process->C, &harq_process->K, &harq_process->Z, // [hna] Z is Zc @@ -464,7 +427,7 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * n_layers; // number of segments to be allocated if (harq_process->C > a_segments) { - LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",harq_process->C,harq_process->B); + LOG_E(PHY, "nr_segmentation.c: too many segments %d, A %d\n", harq_process->C, A); return(-1); } if (nb_rb != 273) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index f3ee7b0e7b..c993ec3709 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -44,6 +44,7 @@ #include "executables/nr-uesoftmodem.h" #include "PHY/CODING/nrLDPC_extern.h" #include "common/utils/nr/nr_common.h" +#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h" #include "openair1/PHY/TOOLS/phy_scope_interface.h" //#define ENABLE_PHY_PAYLOAD_DEBUG 1 @@ -116,10 +117,8 @@ static bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, if (*num_seg_ok == harq_process->C) { if (harq_process->C > 1) { /* check global CRC */ - int A = tbs; - int crc_length = A > 3824 ? 3 : 2; - int crc_type = A > 3824 ? CRC24_A : CRC16; - if (!check_crc(b, A + crc_length * 8, crc_type)) { + // we have regrouped the transport block, so it is "1" segment + if (!check_crc(b, lenWithCrc(1, tbs), crcType(1, tbs))) { harq_process->ack = 0; dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations + 1; LOG_E(PHY, " Frame %d.%d LDPC global CRC fails, but individual LDPC CRC succeeded. %d segs\n", proc->frame_rx, proc->nr_slot_rx, harq_process->C); @@ -166,10 +165,8 @@ static void nr_processDLSegment(void *arg) NR_UE_DLSCH_t *dlsch = rdata->dlsch; NR_DL_UE_HARQ_t *harq_process= rdata->harq_process; t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms; - int length_dec; int Kr; int K_bits_F; - uint8_t crc_type; int r = rdata->segment_r; int A = rdata->A; int E = rdata->E; @@ -240,19 +237,6 @@ static void nr_processDLSegment(void *arg) LOG_D(PHY,"\n"); } - - if (harq_process->C == 1) { - if (A > NR_MAX_PDSCH_TBS) - crc_type = CRC24_A; - else - crc_type = CRC16; - - length_dec = harq_process->B; - } else { - crc_type = CRC24_B; - length_dec = (harq_process->B+24*harq_process->C)/harq_process->C; - } - { start_meas(&rdata->ts_ldpc_decode); //set first 2*Z_c bits to zeros @@ -272,9 +256,9 @@ static void nr_processDLSegment(void *arg) } //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN); - p_decoderParms->block_length=length_dec; - nrLDPC_initcall(p_decoderParms, (int8_t*)&pl[0], LDPCoutput); - p_decoderParms->crc_type = crc_type; + p_decoderParms->block_length = lenWithCrc(harq_process->C, A); + p_decoderParms->crc_type = crcType(harq_process->C, A); + nrLDPC_initcall(p_decoderParms, (int8_t *)&pl[0], LDPCoutput); rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, (int8_t *)&pl[0], LDPCoutput, &procTime, &harq_process->abort_decode); //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT); @@ -311,8 +295,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, // HARQ stats phy_vars_ue->dl_stats[harq_process->DLround]++; - LOG_D(PHY,"Round %d RV idx %d\n",harq_process->DLround,dlsch->dlsch_config.rv); - uint8_t kc; + LOG_D(PHY, "Round %d RV idx %d\n", harq_process->DLround, dlsch->dlsch_config.rv); uint16_t nb_rb;// = 30; uint8_t dmrs_Type = dlsch->dlsch_config.dmrsConfigType; AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type); @@ -377,33 +360,22 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, LOG_D(PHY,"%d.%d DLSCH Decoding, harq_pid %d TBS %d (%d) G %d nb_re_dmrs %d length dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d Qm %d Coderate %f\n", frame,nr_slot_rx,harq_pid,A,A/8,G, nb_re_dmrs, dmrs_length, dlsch->dlsch_config.mcs, dlsch->Nl, nb_symb_sch, nb_rb, dlsch->dlsch_config.qamModOrder, Coderate); - - if ((A <=292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) { - p_decParams->BG = 2; - kc = 52; - } else { - p_decParams->BG = 1; - kc = 68; - } + p_decParams->BG = get_BG(A, dlsch->dlsch_config.targetCodeRate); + unsigned int kc = p_decParams->BG == 2 ? 52 : 68; if (harq_process->first_rx == 1) { // This is a new packet, so compute quantities regarding segmentation - if (A > NR_MAX_PDSCH_TBS) - harq_process->B = A+24; - else - harq_process->B = A+16; - nr_segmentation(NULL, NULL, - harq_process->B, + lenWithCrc(1, A), // We give a max size in case of 1 segment &harq_process->C, &harq_process->K, &harq_process->Z, // [hna] Z is Zc &harq_process->F, p_decParams->BG); - + if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*dlsch->Nl) { - LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",harq_process->C,harq_process->B); + LOG_E(PHY, "nr_segmentation.c: too many segments %d, A %d\n", harq_process->C, A); return(-1); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index 9f9b123781..b0ea45b7ec 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -53,8 +53,6 @@ typedef struct { SCH_status_t status; /// Last TPC command uint8_t TPC; - /// The payload + CRC size in bits, "B" from 36-212 - uint32_t B; /// Length of ACK information (bits) uint8_t O_ACK; /// Index of current HARQ round for this ULSCH @@ -117,8 +115,6 @@ typedef struct { uint8_t Ndi; /// DLSCH status flag indicating SCH_status_t status; - /// The payload + CRC size in bits - uint32_t B; /// Pointers to transport block segments uint8_t **c; /// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 42fe941848..1c4d7c0fec 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -92,8 +92,8 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, */ int max_payload_bytes = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*ulsch->pusch_pdu.nrOfLayers*1056; - - if (A > 3824) { + int B; + if (A > NR_MAX_PDSCH_TBS) { // Add 24-bit crc (polynomial A) to payload crc = crc24a(harq_process->a,A)>>8; harq_process->a[A>>3] = ((uint8_t*)&crc)[2]; @@ -102,13 +102,12 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, //printf("CRC %x (A %d)\n",crc,A); //printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]); - harq_process->B = A+24; + B = A + 24; AssertFatal((A/8)+4 <= max_payload_bytes,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,max_payload_bytes); memcpy(harq_process->b,harq_process->a,(A/8)+4); - } - else { + } else { // Add 16-bit crc (polynomial A) to payload crc = crc16(harq_process->a,A)>>16; harq_process->a[A>>3] = ((uint8_t*)&crc)[1]; @@ -116,7 +115,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, //printf("CRC %x (A %d)\n",crc,A); //printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]); - harq_process->B = A+16; + B = A + 16; AssertFatal((A/8)+3 <= max_payload_bytes,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,max_payload_bytes); @@ -128,26 +127,25 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, ///////////////////////// b---->| block segmentation |---->c ///////////////////////// /////////// - if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ + if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) { harq_process->BG = 2; - } - else{ + } else { harq_process->BG = 1; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_IN); start_meas(&ue->ulsch_segmentation_stats); - uint32_t Kb=nr_segmentation(harq_process->b, - harq_process->c, - harq_process->B, - &harq_process->C, - &harq_process->K, - pz, - &harq_process->F, - harq_process->BG); + uint32_t Kb = nr_segmentation(harq_process->b, + harq_process->c, + B, + &harq_process->C, + &harq_process->K, + pz, + &harq_process->F, + harq_process->BG); if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*ulsch->pusch_pdu.nrOfLayers) { - LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",harq_process->C,harq_process->B); + LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", harq_process->C, B); return(-1); } stop_meas(&ue->ulsch_segmentation_stats); @@ -169,7 +167,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, for (int r=0; rC; r++) { //channel_input[r] = &harq_process->d[r][0]; #ifdef DEBUG_ULSCH_CODING - printf("Encoder: B %d F %d \n",harq_process->B, harq_process->F); + printf("Encoder: B %d F %d \n", B, harq_process->F); printf("start ldpc encoder segment %d/%d\n",r,harq_process->C); printf("input %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]); for (int cnt =0 ; cnt < 22*(*pz)/8; cnt ++){ diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index c2e6dfba75..d212f0c46d 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -75,8 +75,6 @@ typedef struct { nfapi_nr_dl_tti_pdsch_pdu pdsch_pdu; /// pointer to pdu from MAC interface (this is "a" in 36.212) uint8_t *pdu; - /// The payload + CRC size in bits, "B" from 36-212 - uint32_t B; /// Pointer to the payload uint8_t *b; /// Pointers to transport block segments @@ -199,8 +197,6 @@ typedef struct { uint32_t TBS; /// Pointer to the payload (38.212 V15.4.0 section 5.1) uint8_t *b; - /// The payload + CRC (24 bits) in bits (38.212 V15.4.0 section 5.1) - 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; /// Number of bits in each code block (38.212 V15.4.0 section 5.2.2) @@ -227,6 +223,18 @@ typedef struct { int llrLen; ////////////////////////////////////////////////////////////// } NR_UL_gNB_HARQ_t; +static inline int lenWithCrc(int nbSeg, int len) +{ + if (nbSeg > 1) + return (len + 24 + 24 * nbSeg) / nbSeg; + return len + (len > NR_MAX_PDSCH_TBS ? 24 : 16); +} +static inline int crcType(int nbSeg, int len) +{ + if (nbSeg > 1) + return CRC24_B; + return len > NR_MAX_PDSCH_TBS ? CRC24_A : CRC16; +} typedef struct { //! estimated received spatial signal power (linear) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 6ad14f1836..c29cc92795 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -266,12 +266,7 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) // CRC check made by the LDPC for early termination, so, no need to perform CRC check twice for a single code block bool crc_valid = true; if (ulsch_harq->C > 1) { - // Check ULSCH transport block CRC - int crc_type = CRC16; - if (rdata->A > 3824) { - crc_type = CRC24_A; - } - crc_valid = check_crc(ulsch_harq->b, ulsch_harq->B, crc_type); + crc_valid = check_crc(ulsch_harq->b, lenWithCrc(1, rdata->A), crcType(1, rdata->A)); } if (crc_valid && !check_abort(&ulsch_harq->abort_decode) && !gNB->pusch_vars[rdata->ulsch_id].DTX) { diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c index 7ea6df92fc..aa1042491b 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c @@ -26,6 +26,7 @@ #define INDEX_MAX_TBS_TABLE (93) #include "common/utils/nr/nr_common.h" +#include "openair1/PHY/defs_nr_common.h" #include //Table 5.1.2.2-2 @@ -64,7 +65,7 @@ uint32_t nr_compute_tbs(uint16_t Qm, uint32_t nr_tbs=0; uint32_t Np_info, C, n; - if (Ninfo <=3824) { + if (Ninfo <= NR_MAX_PDSCH_TBS) { n = max(3, floor(log2(Ninfo)) - 6); Np_info = max(24, (Ninfo>>n)<>10; - if (Ninfo <=3824) { + if (Ninfo <= NR_MAX_PDSCH_TBS) { n = max(3, floor(log2(Ninfo)) - 6); Np_info = max(24, (Ninfo>>n)< #include @@ -4080,7 +4081,7 @@ void csi_period_offset(NR_CSI_ReportConfig_t *csirep, uint8_t get_BG(uint32_t A, uint16_t R) { float code_rate = (float) R / 10240.0f; - if ((A <=292) || ((A<=3824) && (code_rate <= 0.6667)) || code_rate <= 0.25) + if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (code_rate <= 0.6667)) || code_rate <= 0.25) return 2; else return 1;