From 9586db6bfd3626e71b76752498190d40b9fd88c7 Mon Sep 17 00:00:00 2001 From: Romain Beurdouche Date: Fri, 3 Jan 2025 13:11:46 +0000 Subject: [PATCH 1/6] fix(nrLDPC_decoder): Rename E in Kprime in segment decoder parameters to comply with standard naming --- openair1/PHY/CODING/TESTBENCH/ldpctest.c | 2 +- .../nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c | 2 +- openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c | 2 +- openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h | 2 +- openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index 1dad28c95e..1d0bdfb16b 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -323,7 +323,7 @@ one_measurement_t test_ldpc(short max_iterations, decParams[j].R = code_rate_vec[R_ind]; // 13; decParams[j].numMaxIter = max_iterations; decParams[j].outMode = nrLDPC_outMode_BIT; - decParams[j].E = block_length; + decParams[j].Kprime = block_length; ldpc_toCompare.LDPCinit(); } for (int j = 0; j < n_segments; j++) { 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 e1fec76e23..29d155e95c 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 @@ -193,7 +193,7 @@ static void nr_process_decode_segment(void *arg) memset(rdata->c, 0, Kr_bytes); p_decoderParms->crc_type = crcType(rdata->C, A); - p_decoderParms->E = lenWithCrc(rdata->C, A); + p_decoderParms->Kprime = lenWithCrc(rdata->C, A); // set first 2*Z_c bits to zeros diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c index 4ac8f4799e..fcee71c151 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c @@ -855,7 +855,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, nrLDPC_llr2bitPacked(p_out, p_llrOut, numLLR); else // if (outMode == nrLDPC_outMode_BITINT8) nrLDPC_llr2bit(p_out, p_llrOut, numLLR); - if (p_decParams->check_crc((uint8_t*)p_out, p_decParams->E, p_decParams->crc_type)) { + if (p_decParams->check_crc((uint8_t*)p_out, p_decParams->Kprime, p_decParams->crc_type)) { LOG_D(PHY, "Segment CRC OK, exiting LDPC decoder\n"); break; } diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h index 25e78a542a..57701ce7df 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h @@ -86,7 +86,7 @@ typedef struct nrLDPC_dec_params { uint16_t Z; /**< Lifting size */ uint8_t R; /**< Decoding rate: Format 15,13,... for code rates 1/5, 1/3,... */ uint8_t numMaxIter; /**< Maximum number of iterations */ - int E; + int Kprime; /**< Size of the payload bits and CRC bits in the code block */ e_nrLDPC_outMode outMode; /**< Output format */ int crc_type; int (*check_crc)(uint8_t* decoded_bytes, uint32_t n, uint8_t crc_type); diff --git a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu index ee08e9287c..aa85716947 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu +++ b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu @@ -518,7 +518,7 @@ extern "C" int32_t LDPCdecoder(t_nrLDPC_dec_params *p_decParams, init_LLR_DMA(p_decParams, p_llr, p_out); uint16_t Zc = p_decParams->Z; uint8_t BG = p_decParams->BG; - int block_length = p_decParams->E; + int block_length = p_decParams->Kprime; uint8_t row, col; if (BG == 1) { row = 46; From 15fc29843c255ea7cf75230d03eb90ee9be33b80 Mon Sep 17 00:00:00 2001 From: Romain Beurdouche Date: Fri, 3 Jan 2025 14:43:26 +0000 Subject: [PATCH 2/6] fix(nrLDPC_coding): cleanup the naming of the K, Kprime and Zc variables to comply with the standard 38.212-5.2.2 --- openair1/PHY/CODING/TESTBENCH/ldpctest.c | 2 +- .../nrLDPC_coding/nrLDPC_coding_interface.h | 2 +- .../nrLDPC_coding_segment_decoder.c | 24 ++++----- .../nrLDPC_coding_segment_encoder.c | 6 +-- .../nrLDPC_coding_xdma/nrLDPC_coding_xdma.c | 51 +++++++++---------- openair1/PHY/CODING/nrLDPC_defs.h | 50 +++++++++++------- 6 files changed, 74 insertions(+), 61 deletions(-) diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index 1d0bdfb16b..71c2f1af27 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -259,7 +259,7 @@ one_measurement_t test_ldpc(short max_iterations, printf("To: %d\n", (Kb + nrows - no_punctured_columns) * Zc - removed_bit); printf("number of undecoded bits: %d\n", (Kb + nrows - no_punctured_columns - 2) * Zc - removed_bit); - encoder_implemparams_t impp = {.Zc = Zc, .Kb = Kb, .BG = BG, .Kr = block_length, .K = block_length}; + encoder_implemparams_t impp = {.Zc = Zc, .Kb = Kb, .BG = BG, .K = block_length}; impp.gen_code = 2; if (ntrials==0) diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h index 6492131df3..7544f8cf55 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h @@ -173,7 +173,7 @@ typedef struct nrLDPC_segment_encoding_parameters_s{ * \var G Available radio resource bits * \var tbslbrm Transport block size LBRM * \var A Transport block size (This is A from 38.212 V15.4.0 section 5.1) - * \var Kb Code block size divided by lifting size + * \var Kb Number of time the lifting size needed to fit the payload of a code block * \var K Code block size at input of encoder * \var Z lifting size * \var F filler bits size 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 29d155e95c..df7ba73aed 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 @@ -64,7 +64,8 @@ * \brief decoding parameter of transport blocks * \var decoderParms decoder parameters * \var Qm modulation order - * \var Kc size of base graph input + * \var Kc ratio between the number of columns in the parity check matrix and the lifting size + * it is fixed for a given base graph while the lifting size is chosen to have a sufficient number of columns * \var rv_index * \var max_number_iterations maximum number of LDPC iterations * \var abort_decode pointer to decode abort flag @@ -127,14 +128,13 @@ static void nr_process_decode_segment(void *arg) { nrLDPC_decoding_parameters_t *rdata = (nrLDPC_decoding_parameters_t *)arg; t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms; - const int Kr = rdata->K; - const int Kr_bytes = Kr >> 3; - const int K_bits_F = Kr - rdata->F; + const int K = rdata->K; + const int Kprime = K - rdata->F; const int A = rdata->A; const int E = rdata->E; const int Qm = rdata->Qm; const int rv_index = rdata->rv_index; - const uint8_t kc = rdata->Kc; + const uint8_t Kc = rdata->Kc; short *ulsch_llr = rdata->llr; int8_t llrProcBuf[OAI_LDPC_DECODER_MAX_NUM_LLR] __attribute__((aligned(32))); @@ -177,7 +177,7 @@ static void nr_process_decode_segment(void *arg) *rdata->d_to_be_cleared, E, rdata->F, - Kr - rdata->F - 2 * (p_decoderParms->Z)) + K - rdata->F - 2 * (p_decoderParms->Z)) == -1) { stop_meas(rdata->p_ts_rate_unmatch); @@ -191,7 +191,7 @@ static void nr_process_decode_segment(void *arg) *rdata->d_to_be_cleared = false; - memset(rdata->c, 0, Kr_bytes); + memset(rdata->c, 0, K >> 3); p_decoderParms->crc_type = crcType(rdata->C, A); p_decoderParms->Kprime = lenWithCrc(rdata->C, A); @@ -203,16 +203,16 @@ static void nr_process_decode_segment(void *arg) memset(z, 0, 2 * rdata->Z * sizeof(*z)); // set Filler bits - memset(z + K_bits_F, 127, rdata->F * sizeof(*z)); + memset(z + Kprime, 127, rdata->F * sizeof(*z)); // Move coded bits before filler bits - memcpy(z + 2 * rdata->Z, rdata->d, (K_bits_F - 2 * rdata->Z) * sizeof(*z)); + memcpy(z + 2 * rdata->Z, rdata->d, (Kprime - 2 * rdata->Z) * sizeof(*z)); // skip filler bits - memcpy(z + Kr, rdata->d + (Kr - 2 * rdata->Z), (kc * rdata->Z - Kr) * sizeof(*z)); + memcpy(z + K, rdata->d + (K - 2 * rdata->Z), (Kc * rdata->Z - K) * sizeof(*z)); // Saturate coded bits before decoding into 8 bits values 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 * rdata->Z) >> 4) + 1; i += 2, j++) { + for (int i = 0, j = 0; j < ((Kc * rdata->Z) >> 4) + 1; i += 2, j++) { pl[j] = simde_mm_packs_epi16(pv[i], pv[i + 1]); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -226,7 +226,7 @@ static void nr_process_decode_segment(void *arg) ldpc_interface_segment.LDPCdecoder(p_decoderParms, 0, 0, 0, l, llrProcBuf, p_procTime, rdata->abort_decode); if (decodeIterations <= p_decoderParms->numMaxIter) { - memcpy(rdata->c,llrProcBuf, Kr>>3); + memcpy(rdata->c,llrProcBuf, K>>3); *rdata->decodeSuccess = true; } else { *rdata->decodeSuccess = false; diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c index 6c66edeb82..8a3291eeae 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c @@ -61,7 +61,7 @@ static void ldpc8blocks_coding_segment(void *p) uint32_t A = nrLDPC_TB_encoding_parameters->A; unsigned int G = nrLDPC_TB_encoding_parameters->G; - LOG_D(PHY,"dlsch coding A %d Kr %d G %d (nb_rb %d, mod_order %d)\n", + LOG_D(PHY,"dlsch coding A %d K %d G %d (nb_rb %d, mod_order %d)\n", A,impp->K,G, nb_rb,(int)mod_order); // nrLDPC_encoder output is in "d" @@ -123,7 +123,7 @@ static void ldpc8blocks_coding_segment(void *p) stop_meas(&nrLDPC_TB_encoding_parameters->segments[rr].ts_rate_match); if (impp->K - impp->F - 2 * impp->Zc > E) { LOG_E(PHY, - "dlsch coding A %d Kr %d G %d (nb_rb %d, mod_order %d)\n", + "dlsch coding A %d K %d G %d (nb_rb %d, mod_order %d)\n", A, impp->K, G, @@ -131,7 +131,7 @@ static void ldpc8blocks_coding_segment(void *p) (int)mod_order); LOG_E(NR_PHY, - "Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Kr %d, Filler bits %d, Filler offset %d mod_order %d, " + "Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, K %d, Filler bits %d, Filler offset %d mod_order %d, " "nb_rb %d)...\n", rr, impp->n_segments, 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 057fb58f6a..11fcd31424 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 @@ -83,8 +83,8 @@ typedef struct args_fpga_decode_prepare_s { uint32_t r_span; /*!< number of blocks to be prepared within this function */ int r_offset; /*!< r index expressed in bits */ int input_CBoffset; /*!< */ - int kc; /*!< */ - int K_bits_F; /*!< */ + int Kc; /*!< ratio between the number of columns in the parity check graph and the lifting size */ + int Kprime; /*!< size of payload and CRC bits in a code block */ task_ans_t *ans; /*!< pointer to the answer that is used by thread pool to detect job completion */ } args_fpga_decode_prepare_t; @@ -143,11 +143,10 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, int slot_rx, tpool_t *ldpc_threadPool) { - const uint32_t Kr = TB_params->K; - const uint32_t Kr_bytes = Kr >> 3; - const int kc = TB_params->BG == 2 ? 52 : 68; + const uint32_t K = TB_params->K; + const int Kc = TB_params->BG == 2 ? 52 : 68; int r_offset = 0, offset = 0; - int K_bits_F = Kr - TB_params->F; + int Kprime = K - TB_params->F; // FPGA parameter preprocessing static uint8_t multi_indata[27000 * 25]; // FPGA input data @@ -156,7 +155,7 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, int bg_len = TB_params->BG == 1 ? 22 : 10; // Calc input CB offset - int input_CBoffset = TB_params->Z * kc * 8; + int input_CBoffset = TB_params->Z * Kc * 8; if ((input_CBoffset & 0x7F) == 0) input_CBoffset = input_CBoffset / 8; else @@ -168,7 +167,7 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, dec_conf.max_iter = TB_params->max_ldpc_iterations; dec_conf.numCB = TB_params->C; // input soft bits length, Zc x 66 - length of filler bits - dec_conf.numChannelLls = (K_bits_F - 2 * TB_params->Z) + (kc * TB_params->Z - Kr); + dec_conf.numChannelLls = (Kprime - 2 * TB_params->Z) + (Kc * TB_params->Z - K); // filler bits length dec_conf.numFillerBits = TB_params->F; dec_conf.max_schedule = 0; @@ -196,11 +195,11 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, printf("TB_params->F: %d\n", TB_params->F); printf("numChannelLls:\t %d = (%d - 2 * %d) + (%d * %d - %d)\n", dec_conf.numChannelLls, - K_bits_F, + Kprime, TB_params->Z, - kc, + Kc, TB_params->Z, - Kr); + K); printf("numFillerBits:\t %d\n", TB_params->F); printf("------------------------\n"); // =================================== @@ -265,8 +264,8 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, args->r_span = r_span; args->r_offset = r_offset; args->input_CBoffset = input_CBoffset; - args->kc = kc; - args->K_bits_F = K_bits_F; + args->Kc = Kc; + args->Kprime = Kprime; r_remaining = r_span; @@ -276,7 +275,7 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, LOG_D(PHY, "Added %d block(s) to prepare for decoding, in pipe: %d to %d\n", r_span, r, r + r_span - 1); } r_offset += segment_params->E; - offset += (Kr_bytes - (TB_params->F >> 3) - ((TB_params->C > 1) ? 3 : 0)); + offset += ((K >> 3) - (TB_params->F >> 3) - ((TB_params->C > 1) ? 3 : 0)); r_remaining -= 1; } @@ -353,7 +352,7 @@ void nr_ulsch_FPGA_decoding_prepare_blocks(void *args) uint8_t max_ldpc_iterations = TB_params->max_ldpc_iterations; uint32_t tbslbrm = TB_params->tbslbrm; - uint32_t Kr = TB_params->K; + uint32_t K = TB_params->K; uint32_t Z = TB_params->Z; uint32_t F = TB_params->F; @@ -369,8 +368,8 @@ void nr_ulsch_FPGA_decoding_prepare_blocks(void *args) uint32_t r_span = arguments->r_span; int r_offset = arguments->r_offset; int input_CBoffset = arguments->input_CBoffset; - int kc = arguments->kc; - int K_bits_F = arguments->K_bits_F; + int Kc = arguments->Kc; + int Kprime = arguments->Kprime; int16_t z[68 * 384 + 16] __attribute__((aligned(16))); simde__m128i *pv = (simde__m128i *)&z; @@ -405,7 +404,7 @@ void nr_ulsch_FPGA_decoding_prepare_blocks(void *args) *segment_params->d_to_be_cleared, segment_params->E, F, - Kr - F - 2 * Z) + K - F - 2 * Z) == -1) { stop_meas(&segment_params->ts_rate_unmatch); LOG_E(PHY, "ulsch_decoding.c: Problem in rate_matching\n"); @@ -418,33 +417,33 @@ void nr_ulsch_FPGA_decoding_prepare_blocks(void *args) *segment_params->d_to_be_cleared = false; - memset(segment_params->c, 0, Kr >> 3); + memset(segment_params->c, 0, K >> 3); // set first 2*Z_c bits to zeros memset(&z[0], 0, 2 * Z * sizeof(int16_t)); // set Filler bits - memset((&z[0] + K_bits_F), 127, F * sizeof(int16_t)); + memset((&z[0] + Kprime), 127, F * sizeof(int16_t)); // Move coded bits before filler bits - memcpy((&z[0] + 2 * Z), segment_params->d, (K_bits_F - 2 * Z) * sizeof(int16_t)); + memcpy((&z[0] + 2 * Z), segment_params->d, (Kprime - 2 * Z) * sizeof(int16_t)); // skip filler bits - memcpy((&z[0] + Kr), segment_params->d + (Kr - 2 * Z), (kc * Z - Kr) * sizeof(int16_t)); + memcpy((&z[0] + K), segment_params->d + (K - 2 * Z), (Kc * Z - K) * sizeof(int16_t)); // Saturate coded bits before decoding into 8 bits values - for (int i = 0, j = 0; j < ((kc * Z) >> 4); i += 2, j++) { + for (int i = 0, j = 0; j < ((Kc * Z) >> 4); i += 2, j++) { temp_multi_indata[j] = simde_mm_xor_si128(simde_mm_packs_epi16(pv[i], pv[i + 1]), simde_mm_cmpeq_epi32(ones, ones)); // Perform NOT operation and write the result to temp_multi_indata[j] } - // the last bytes before reaching "kc * harq_process->Z" should not be written 128 bits at a time to avoid overwritting the + // the last bytes before reaching "Kc * harq_process->Z" should not be written 128 bits at a time to avoid overwritting the // following block in multi_indata simde__m128i tmp = - simde_mm_xor_si128(simde_mm_packs_epi16(pv[2 * ((kc * Z) >> 4)], pv[2 * ((kc * Z) >> 4) + 1]), + simde_mm_xor_si128(simde_mm_packs_epi16(pv[2 * ((Kc * Z) >> 4)], pv[2 * ((Kc * Z) >> 4) + 1]), simde_mm_cmpeq_epi32(ones, ones)); // Perform NOT operation and write the result to temp_multi_indata[j] uint8_t *tmp_p = (uint8_t *)&tmp; - for (int i = 0, j = ((kc * Z) & 0xfffffff0); j < kc * Z; i++, j++) { + for (int i = 0, j = ((Kc * Z) & 0xfffffff0); j < Kc * Z; i++, j++) { multi_indata[r * input_CBoffset + j] = tmp_p[i]; } diff --git a/openair1/PHY/CODING/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_defs.h index 471498be74..fe386ce6d7 100644 --- a/openair1/PHY/CODING/nrLDPC_defs.h +++ b/openair1/PHY/CODING/nrLDPC_defs.h @@ -26,37 +26,51 @@ #include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" /** - \brief LDPC encoder - \param 1 input - \param 2 channel_input - \param 3 int Zc - \param 4 int Kb - \param 5 short block_length - \param 6 short BG - \param 7 int n_segment - \param 8 unsigned int macro_num - \param 9-12 time_stats_t *tinput,*tprep, *tparity,*toutput + \brief LDPC encoder parameter structure + \var n_segments number of segments in the transport block + \var macro_num index of the subset of segments to encode + within the transport block + \var gen_code flag to generate parity check code + 0 -> encoding + 1 -> generate parity check code with AVX2 + 2 -> generate parity check code without AVX2 + \var tinput time statistics for data input in the encoder + \var tprep time statistics for data preparation in the encoder + \var tparity time statistics for adding parity bits + \var toutput time statistics for data output from the encoder + \var K size of the complete code segment before encoding + including payload, CRC bits and filler bit + (also known as Kr, see 38.212-5.2.2) + \var Kb number of lifting sizes to fit the payload (see 38.212-5.2.2) + \var Zc lifting size (see 38.212-5.2.2) + \var F number of filler bits (see 38.212-5.2.2) + \var harq pointer to the HARQ process structure + \var BG base graph index + \var output output buffer after INTERLEAVING + \var ans pointer to the task answer + to notify thread pool about completion of the task */ typedef struct { - unsigned int n_segments; // optim8seg - unsigned int macro_num; // optim8segmulti - unsigned char gen_code; //orig + unsigned int n_segments; // optim8seg + unsigned int macro_num; // optim8segmulti + unsigned char gen_code; //orig time_stats_t *tinput; time_stats_t *tprep; time_stats_t *tparity; time_stats_t *toutput; - int Kr; + /// Size in bits of the code segments + uint32_t K; + /// Number of lifting sizes to fit the payload uint32_t Kb; + /// Lifting size uint32_t Zc; + /// Number of "Filler" bits + uint32_t F; void *harq; /// Encoder BG uint8_t BG; /// Interleaver outputs unsigned char *output; - /// Number of bits in "small" code segments - uint32_t K; - /// Number of "Filler" bits - uint32_t F; task_ans_t *ans; } encoder_implemparams_t; From c959f41987be3a07788258a6d45066d5637a0ae5 Mon Sep 17 00:00:00 2001 From: Romain Beurdouche Date: Mon, 6 Jan 2025 08:13:01 +0000 Subject: [PATCH 3/6] fix(nrLDPC_coding): remove T2 legacy setCombIn from segment decoder parameters --- .../nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c | 1 - openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) 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 df7ba73aed..8ac20841b9 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 @@ -257,7 +257,6 @@ int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_de t_info->len += 1; decParams.R = nrLDPC_TB_decoding_parameters->segments[r].R; - decParams.setCombIn = !nrLDPC_TB_decoding_parameters->segments[r].d_to_be_cleared; rdata->decoderParms = decParams; rdata->llr = nrLDPC_TB_decoding_parameters->segments[r].llr; rdata->Kc = decParams.BG == 2 ? 52 : 68; diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h index 57701ce7df..abe5d38a50 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h @@ -88,9 +88,8 @@ typedef struct nrLDPC_dec_params { uint8_t numMaxIter; /**< Maximum number of iterations */ int Kprime; /**< Size of the payload bits and CRC bits in the code block */ e_nrLDPC_outMode outMode; /**< Output format */ - int crc_type; - int (*check_crc)(uint8_t* decoded_bytes, uint32_t n, uint8_t crc_type); - uint8_t setCombIn; + int crc_type; /**< Size and type of the parity check bits (16, 24A or 24B) */ + int (*check_crc)(uint8_t* decoded_bytes, uint32_t n, uint8_t crc_type); /**< Parity check function */ } t_nrLDPC_dec_params; /** From 6eb0913de930f2510c3a0d86257ca12809aa7303 Mon Sep 17 00:00:00 2001 From: Romain Beurdouche Date: Wed, 8 Jan 2025 09:27:01 +0000 Subject: [PATCH 4/6] fix(documentation): typos and strengthen the explanation of the adaptation layer between slot coding and segment coding --- openair1/PHY/CODING/DOC/LDPCImplementation.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/CODING/DOC/LDPCImplementation.md b/openair1/PHY/CODING/DOC/LDPCImplementation.md index f5260e4d0a..cf5fb506c8 100644 --- a/openair1/PHY/CODING/DOC/LDPCImplementation.md +++ b/openair1/PHY/CODING/DOC/LDPCImplementation.md @@ -114,9 +114,11 @@ Libraries implementing the slotwise LDPC coding must be named `libldpc<_version> The interface of the library is defined in [nrLDPC_defs.h](file://../nrLDPC_defs.h). The code loading the LDPC library is in [nrLDPC_load.c](file://../nrLDPC_load.c), in function `load_nrLDPClib`, which must be called at init time. +*Note: LDPC segment coding libraries are not loaded directly by OAI but by the intermediate library `libldpc.so` which is implementing the LDPC slot coding interface using a LDPC segment coding library.* + ### Selecting the LDPC library at run time -By default the function `int load_nrLDPClib(void)` looks for `libldpc.so`, this default behavior can be changed using the oai loader configuration options in the configuration file or from the command line as shown below: +By default the function `int load_nrLDPClib(void)` looks for `libldpc_optim8segmulti.so`, this default behavior can be changed using the oai loader configuration options in the configuration file or from the command line as shown below: #### Examples of ldpc shared lib selection when running nr softmodem's: @@ -133,7 +135,7 @@ loading `libldpc_optim8seg.so` instead of `libldpc_optim8segmulti.so`: ........................ ``` -loading `libldpc_cl.so` instead of `libldpc.so`: +loading `libldpc_cl.so` instead of `libldpc_optim8segmulti.so`: `make ldpc_cl` From c54e7a70351c5f8678e59467f1aed8b1d732543d Mon Sep 17 00:00:00 2001 From: Romain Beurdouche Date: Thu, 9 Jan 2025 07:57:41 +0000 Subject: [PATCH 5/6] fix(nrLDPC_coding): in segment decoder, move useless memset on decoder output c to the oly case where it is useful --- .../nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8ac20841b9..bccf9619b3 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 @@ -191,7 +191,6 @@ static void nr_process_decode_segment(void *arg) *rdata->d_to_be_cleared = false; - memset(rdata->c, 0, K >> 3); p_decoderParms->crc_type = crcType(rdata->C, A); p_decoderParms->Kprime = lenWithCrc(rdata->C, A); @@ -229,6 +228,7 @@ static void nr_process_decode_segment(void *arg) memcpy(rdata->c,llrProcBuf, K>>3); *rdata->decodeSuccess = true; } else { + memset(rdata->c, 0, K >> 3); *rdata->decodeSuccess = false; } stop_meas(rdata->p_ts_ldpc_decode); From f9c7057ed1b0dda3ec4306cad54c764b1e1a5509 Mon Sep 17 00:00:00 2001 From: Romain Beurdouche Date: Thu, 9 Jan 2025 07:59:37 +0000 Subject: [PATCH 6/6] fix(nrLDPC_coding): Apply clang-format to segment coding code --- .../nrLDPC_coding_segment_decoder.c | 45 +++++-------- .../nrLDPC_coding_segment_encoder.c | 66 ++++++++----------- .../nrLDPC_coding_xdma/nrLDPC_coding_xdma.c | 30 ++++----- 3 files changed, 57 insertions(+), 84 deletions(-) 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 bccf9619b3..f14e09f8b4 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 @@ -20,9 +20,8 @@ */ /*! \file PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c -* \brief Top-level routines for decoding LDPC transport channels -*/ - + * \brief Top-level routines for decoding LDPC transport channels + */ // [from gNB coding] #include "PHY/defs_gNB.h" @@ -45,10 +44,10 @@ #include #include #include -//#define gNB_DEBUG_TRACE +// #define gNB_DEBUG_TRACE -#define OAI_LDPC_DECODER_MAX_NUM_LLR 27000 //26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384 -//#define DEBUG_CRC +#define OAI_LDPC_DECODER_MAX_NUM_LLR 27000 // 26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384 +// #define DEBUG_CRC #ifdef DEBUG_CRC #define PRINT_CRC_CHECK(a) a #else @@ -76,7 +75,7 @@ * \var F filler bits size * \var r segment index in TB * \var E input llr segment size - * \var C number of segments + * \var C number of segments * \var llr input llr segment array * \var d Pointers to code blocks before LDPC decoding (38.212 V15.4.0 section 5.3.2) * \var d_to_be_cleared @@ -89,8 +88,7 @@ * \var p_ts_rate_unmatch pointer to rate unmatching time stats * \var p_ts_ldpc_decode pointer to decoding time stats */ -typedef struct nrLDPC_decoding_parameters_s{ - +typedef struct nrLDPC_decoding_parameters_s { t_nrLDPC_dec_params decoderParms; uint8_t Qm; @@ -166,7 +164,6 @@ static void nr_process_decode_segment(void *arg) ///////////////////////// ulsch_harq->e =====> ulsch_harq->d ///////////////////////// - if (nr_rate_matching_ldpc_rx(rdata->tbslbrm, p_decoderParms->BG, p_decoderParms->Z, @@ -179,7 +176,6 @@ static void nr_process_decode_segment(void *arg) rdata->F, K - rdata->F - 2 * (p_decoderParms->Z)) == -1) { - stop_meas(rdata->p_ts_rate_unmatch); LOG_E(PHY, "nrLDPC_coding_segment_decoder.c: Problem in rate_matching\n"); @@ -225,7 +221,7 @@ static void nr_process_decode_segment(void *arg) ldpc_interface_segment.LDPCdecoder(p_decoderParms, 0, 0, 0, l, llrProcBuf, p_procTime, rdata->abort_decode); if (decodeIterations <= p_decoderParms->numMaxIter) { - memcpy(rdata->c,llrProcBuf, K>>3); + memcpy(rdata->c, llrProcBuf, K >> 3); *rdata->decodeSuccess = true; } else { memset(rdata->c, 0, K >> 3); @@ -237,9 +233,10 @@ static void nr_process_decode_segment(void *arg) completed_task_ans(rdata->ans); } -int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_decoding_parameters, int pusch_id, thread_info_tm_t *t_info) +int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_decoding_parameters, + int pusch_id, + thread_info_tm_t *t_info) { - nrLDPC_TB_decoding_parameters_t *nrLDPC_TB_decoding_parameters = &nrLDPC_slot_decoding_parameters->TBs[pusch_id]; *nrLDPC_TB_decoding_parameters->processedSegments = 0; @@ -250,7 +247,6 @@ int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_de decParams.outMode = 0; for (int r = 0; r < nrLDPC_TB_decoding_parameters->C; r++) { - nrLDPC_decoding_parameters_t *rdata = &((nrLDPC_decoding_parameters_t *)t_info->buf)[t_info->len]; DevAssert(t_info->len < t_info->cap); rdata->ans = &t_info->ans[t_info->len]; @@ -286,29 +282,26 @@ int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_de return nrLDPC_TB_decoding_parameters->C; } -int32_t nrLDPC_coding_init(void){ - +int32_t nrLDPC_coding_init(void) +{ char *segment_shlibversion = NULL; paramdef_t LoaderParams[] = { - {"segment_shlibversion", NULL, 0, .strptr = &segment_shlibversion, .defstrval = "_optim8segmulti", TYPE_STRING, 0, NULL} - }; + {"segment_shlibversion", NULL, 0, .strptr = &segment_shlibversion, .defstrval = "_optim8segmulti", TYPE_STRING, 0, NULL}}; config_get(config_get_if(), LoaderParams, sizeofArray(LoaderParams), "nrLDPC_coding_segment"); load_LDPClib(segment_shlibversion, &ldpc_interface_segment); return 0; - } -int32_t nrLDPC_coding_shutdown(void){ - +int32_t nrLDPC_coding_shutdown(void) +{ free_LDPClib(&ldpc_interface_segment); return 0; - } -int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_decoding_parameters){ - +int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_decoding_parameters) +{ int nbSegments = 0; for (int pusch_id = 0; pusch_id < nrLDPC_slot_decoding_parameters->nb_TBs; pusch_id++) { nrLDPC_TB_decoding_parameters_t *nrLDPC_TB_decoding_parameters = &nrLDPC_slot_decoding_parameters->TBs[pusch_id]; @@ -338,6 +331,4 @@ int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_dec } } return 0; - } - diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c index 8a3291eeae..c096e1967a 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c @@ -20,8 +20,8 @@ */ /*! \file PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c -* \brief Top-level routines for implementing LDPC encoding of transport channels -*/ + * \brief Top-level routines for implementing LDPC encoding of transport channels + */ #include "PHY/defs_gNB.h" #include "PHY/CODING/coding_extern.h" @@ -40,8 +40,8 @@ #include -//#define DEBUG_LDPC_ENCODING -//#define DEBUG_LDPC_ENCODING_FREE 1 +// #define DEBUG_LDPC_ENCODING +// #define DEBUG_LDPC_ENCODING_FREE 1 extern ldpc_interface_t ldpc_interface_segment; @@ -61,35 +61,34 @@ static void ldpc8blocks_coding_segment(void *p) uint32_t A = nrLDPC_TB_encoding_parameters->A; unsigned int G = nrLDPC_TB_encoding_parameters->G; - LOG_D(PHY,"dlsch coding A %d K %d G %d (nb_rb %d, mod_order %d)\n", - A,impp->K,G, nb_rb,(int)mod_order); + LOG_D(PHY, "dlsch coding A %d K %d G %d (nb_rb %d, mod_order %d)\n", A, impp->K, G, nb_rb, (int)mod_order); // nrLDPC_encoder output is in "d" // let's make this interface happy! - uint8_t tmp[8][68 * 384]__attribute__((aligned(32))); + uint8_t tmp[8][68 * 384] __attribute__((aligned(32))); uint8_t *d[impp->n_segments]; - for (int rr=impp->macro_num*8, i=0; rr < impp->n_segments && rr < (impp->macro_num+1)*8; rr++,i++ ) + for (int rr = impp->macro_num * 8, i = 0; rr < impp->n_segments && rr < (impp->macro_num + 1) * 8; rr++, i++) d[rr] = tmp[i]; uint8_t *c[nrLDPC_TB_encoding_parameters->C]; for (int r = 0; r < nrLDPC_TB_encoding_parameters->C; r++) - c[r]=nrLDPC_TB_encoding_parameters->segments[r].c; - start_meas(&nrLDPC_TB_encoding_parameters->segments[impp->macro_num*8].ts_ldpc_encode); + c[r] = nrLDPC_TB_encoding_parameters->segments[r].c; + start_meas(&nrLDPC_TB_encoding_parameters->segments[impp->macro_num * 8].ts_ldpc_encode); ldpc_interface_segment.LDPCencoder(c, d, impp); - stop_meas(&nrLDPC_TB_encoding_parameters->segments[impp->macro_num*8].ts_ldpc_encode); + stop_meas(&nrLDPC_TB_encoding_parameters->segments[impp->macro_num * 8].ts_ldpc_encode); // Compute where to place in output buffer that is concatenation of all segments - uint32_t r_offset=0; - for (int i=0; i < impp->macro_num*8; i++ ) - r_offset+=nrLDPC_TB_encoding_parameters->segments[i].E; - for (int rr=impp->macro_num*8; rr < impp->n_segments && rr < (impp->macro_num+1)*8; rr++ ) { - if (impp->F>0) { + uint32_t r_offset = 0; + for (int i = 0; i < impp->macro_num * 8; i++) + r_offset += nrLDPC_TB_encoding_parameters->segments[i].E; + for (int rr = impp->macro_num * 8; rr < impp->n_segments && rr < (impp->macro_num + 1) * 8; rr++) { + if (impp->F > 0) { // writing into positions d[r][k-2Zc] as in clause 5.3.2 step 2) in 38.212 memset(&d[rr][impp->K - impp->F - 2 * impp->Zc], NR_NULL, impp->F); } #ifdef DEBUG_LDPC_ENCODING - LOG_D(PHY,"rvidx in encoding = %d\n", rel15->rvIndex[0]); + LOG_D(PHY, "rvidx in encoding = %d\n", rel15->rvIndex[0]); #endif uint32_t E = nrLDPC_TB_encoding_parameters->segments[rr].E; LOG_D(NR_PHY, @@ -108,7 +107,7 @@ static void ldpc8blocks_coding_segment(void *p) uint32_t Tbslbrm = nrLDPC_TB_encoding_parameters->tbslbrm; uint8_t e[E]; - bzero (e, E); + bzero(e, E); start_meas(&nrLDPC_TB_encoding_parameters->segments[rr].ts_rate_match); nr_rate_matching_ldpc(Tbslbrm, impp->BG, @@ -122,13 +121,7 @@ static void ldpc8blocks_coding_segment(void *p) E); stop_meas(&nrLDPC_TB_encoding_parameters->segments[rr].ts_rate_match); if (impp->K - impp->F - 2 * impp->Zc > E) { - LOG_E(PHY, - "dlsch coding A %d K %d G %d (nb_rb %d, mod_order %d)\n", - A, - impp->K, - G, - nb_rb, - (int)mod_order); + LOG_E(PHY, "dlsch coding A %d K %d G %d (nb_rb %d, mod_order %d)\n", A, impp->K, G, nb_rb, (int)mod_order); LOG_E(NR_PHY, "Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, K %d, Filler bits %d, Filler offset %d mod_order %d, " @@ -145,23 +138,20 @@ static void ldpc8blocks_coding_segment(void *p) } #ifdef DEBUG_LDPC_ENCODING - for (int i =0; i<16; i++) - printf("output ratematching e[%d]= %d r_offset %u\n", i,e[i], r_offset); + for (int i = 0; i < 16; i++) + printf("output ratematching e[%d]= %d r_offset %u\n", i, e[i], r_offset); #endif start_meas(&nrLDPC_TB_encoding_parameters->segments[rr].ts_interleave); - nr_interleaving_ldpc(E, - mod_order, - e, - impp->output+r_offset); + nr_interleaving_ldpc(E, mod_order, e, impp->output + r_offset); stop_meas(&nrLDPC_TB_encoding_parameters->segments[rr].ts_interleave); #ifdef DEBUG_LDPC_ENCODING - for (int i =0; i<16; i++) - printf("output interleaving f[%d]= %d r_offset %u\n", i,impp->output[i+r_offset], r_offset); + for (int i = 0; i < 16; i++) + printf("output interleaving f[%d]= %d r_offset %u\n", i, impp->output[i + r_offset], r_offset); - if (r==impp->n_segments-1) - write_output("enc_output.m","enc",impp->output,G,1,4); + if (r == impp->n_segments - 1) + write_output("enc_output.m", "enc", impp->output, G, 1, 4); #endif r_offset += E; @@ -171,7 +161,9 @@ static void ldpc8blocks_coding_segment(void *p) completed_task_ans(impp->ans); } -static int nrLDPC_prepare_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters, int dlsch_id, thread_info_tm_t *t_info) +static int nrLDPC_prepare_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters, + int dlsch_id, + thread_info_tm_t *t_info) { nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters = &nrLDPC_slot_encoding_parameters->TBs[dlsch_id]; @@ -211,7 +203,6 @@ static int nrLDPC_prepare_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters) { - int nbTasks = 0; for (int dlsch_id = 0; dlsch_id < nrLDPC_slot_encoding_parameters->nb_TBs; dlsch_id++) { nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters = &nrLDPC_slot_encoding_parameters->TBs[dlsch_id]; @@ -234,5 +225,4 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin join_task_ans(ans, nbEncode); return 0; - } 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 11fcd31424..67e26e2aff 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 @@ -92,24 +92,20 @@ int32_t nrLDPC_coding_init(void); int32_t nrLDPC_coding_shutdown(void); int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *slot_params, int frame_rx, int slot_rx); // int32_t nrLDPC_coding_encoder(void); -int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, - int frame_rx, - int slot_rx, - tpool_t *ldpc_threadPool); +int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, int frame_rx, int slot_rx, tpool_t *ldpc_threadPool); void nr_ulsch_FPGA_decoding_prepare_blocks(void *args); int32_t nrLDPC_coding_init(void) { char *encoder_shlibversion = NULL; paramdef_t LoaderParams[] = { - {"num_threads_prepare", NULL, 0, .iptr = &num_threads_prepare_max, .defintval = 0, TYPE_INT, 0, NULL}, - {"encoder_shlibversion", NULL, 0, .strptr = &encoder_shlibversion, .defstrval = "_optim8segmulti", TYPE_STRING, 0, NULL}, - {"user_device", NULL, 0, .strptr = &user_device, .defstrval = DEVICE_NAME_DEFAULT_USER, TYPE_STRING, 0, NULL}, - {"enc_read_device", NULL, 0, .strptr = &enc_read_device, .defstrval = DEVICE_NAME_DEFAULT_ENC_READ, TYPE_STRING, 0, NULL}, - {"enc_write_device", NULL, 0, .strptr = &enc_write_device, .defstrval = DEVICE_NAME_DEFAULT_ENC_WRITE, TYPE_STRING, 0, NULL}, - {"dec_read_device", NULL, 0, .strptr = &dec_read_device, .defstrval = DEVICE_NAME_DEFAULT_DEC_READ, TYPE_STRING, 0, NULL}, - {"dec_write_device", NULL, 0, .strptr = &dec_write_device, .defstrval = DEVICE_NAME_DEFAULT_DEC_WRITE, TYPE_STRING, 0, NULL} - }; + {"num_threads_prepare", NULL, 0, .iptr = &num_threads_prepare_max, .defintval = 0, TYPE_INT, 0, NULL}, + {"encoder_shlibversion", NULL, 0, .strptr = &encoder_shlibversion, .defstrval = "_optim8segmulti", TYPE_STRING, 0, NULL}, + {"user_device", NULL, 0, .strptr = &user_device, .defstrval = DEVICE_NAME_DEFAULT_USER, TYPE_STRING, 0, NULL}, + {"enc_read_device", NULL, 0, .strptr = &enc_read_device, .defstrval = DEVICE_NAME_DEFAULT_ENC_READ, TYPE_STRING, 0, NULL}, + {"enc_write_device", NULL, 0, .strptr = &enc_write_device, .defstrval = DEVICE_NAME_DEFAULT_ENC_WRITE, TYPE_STRING, 0, NULL}, + {"dec_read_device", NULL, 0, .strptr = &dec_read_device, .defstrval = DEVICE_NAME_DEFAULT_DEC_READ, TYPE_STRING, 0, NULL}, + {"dec_write_device", NULL, 0, .strptr = &dec_write_device, .defstrval = DEVICE_NAME_DEFAULT_DEC_WRITE, TYPE_STRING, 0, NULL}}; config_get(config_get_if(), LoaderParams, sizeofArray(LoaderParams), "nrLDPC_coding_xdma"); AssertFatal(num_threads_prepare_max != 0, "nrLDPC_coding_xdma.num_threads_prepare was not provided"); @@ -138,10 +134,7 @@ int32_t nrLDPC_coding_encoder(void) } */ -int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, - int frame_rx, - int slot_rx, - tpool_t *ldpc_threadPool) +int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, int frame_rx, int slot_rx, tpool_t *ldpc_threadPool) { const uint32_t K = TB_params->K; const int Kc = TB_params->BG == 2 ? 52 : 68; @@ -220,10 +213,9 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, // calculate required number of jobs uint32_t r_while = 0; while (r_while < TB_params->C) { - // calculate number of segments processed in the new job uint32_t modulus = (TB_params->C - r_while) % (num_threads_prepare_max - num_threads_prepare); - uint32_t quotient = (TB_params->C - r_while) / (num_threads_prepare_max - num_threads_prepare); + uint32_t quotient = (TB_params->C - r_while) / (num_threads_prepare_max - num_threads_prepare); uint32_t r_span_max = modulus == 0 ? quotient : quotient + 1; // saturate to be sure to not go above C @@ -257,7 +249,7 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, args->r_first = r; uint32_t modulus = (TB_params->C - r) % (num_threads_prepare_max - num_threads_prepare); - uint32_t quotient = (TB_params->C - r) / (num_threads_prepare_max - num_threads_prepare); + uint32_t quotient = (TB_params->C - r) / (num_threads_prepare_max - num_threads_prepare); uint32_t r_span_max = modulus == 0 ? quotient : quotient + 1; uint32_t r_span = TB_params->C - r < r_span_max ? TB_params->C - r : r_span_max;