From 766a43225dfe7ce7a4ba24c89391264b44768a3e Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 5 Nov 2020 18:51:41 +0100 Subject: [PATCH] 5G FEC extension --- lib/include/srslte/phy/fec/cbsegm.h | 5 ++++- lib/src/phy/fec/cbsegm.c | 29 +++++++++++++++++++++++++++-- lib/src/phy/fec/ldpc/ldpc_rm.c | 8 +------- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/lib/include/srslte/phy/fec/cbsegm.h b/lib/include/srslte/phy/fec/cbsegm.h index ab87960d5..35cb9a418 100644 --- a/lib/include/srslte/phy/fec/cbsegm.h +++ b/lib/include/srslte/phy/fec/cbsegm.h @@ -39,6 +39,9 @@ typedef struct SRSLTE_API { uint32_t C1; ///< \brief Number of code blocks of size 1 uint32_t C2; ///< \brief Number of code blocks of size 2 uint32_t tbs; ///< \brief Actual transport block size + uint32_t L_tb; ///< \brief Transport block CRC length + uint32_t L_cb; ///< \brief Code block CRC length + uint32_t Z; ///< \brief Lifting size, LDPC only } srslte_cbsegm_t; /** @@ -97,6 +100,6 @@ SRSLTE_API int srslte_cbsegm_ldpc_bg1(srslte_cbsegm_t* s, uint32_t tbs); * @param[in] tbs Input Transport Block Size in bits. CRC's will be added to this * @return It returns SRSLTE_SUCCESS if the provided arguments are valid, otherwise it returns SRSLTE_ERROR code */ -SRSLTE_API int srslte_cbsegm_nr_bg2(srslte_cbsegm_t* s, uint32_t tbs); +SRSLTE_API int srslte_cbsegm_ldpc_bg2(srslte_cbsegm_t* s, uint32_t tbs); #endif // SRSLTE_CBSEGM_H diff --git a/lib/src/phy/fec/cbsegm.c b/lib/src/phy/fec/cbsegm.c index 2797f56dd..76e66f1e6 100644 --- a/lib/src/phy/fec/cbsegm.c +++ b/lib/src/phy/fec/cbsegm.c @@ -97,7 +97,9 @@ int srslte_cbsegm(srslte_cbsegm_t* s, uint32_t tbs) s->C2 = (s->C * s->K1 - Bp) / (s->K1 - s->K2); s->C1 = s->C - s->C2; } - s->F = s->C1 * s->K1 + s->C2 * s->K2 - Bp; + s->L_tb = 24; // 24 bit CRC always + s->L_cb = 24; // 24 bit CRC always + s->F = s->C1 * s->K1 + s->C2 * s->K2 - Bp; INFO("CB Segmentation: TBS: %d, C=%d, C+=%d K+=%d, C-=%d, K-=%d, F=%d, Bp=%d\n", tbs, s->C, @@ -187,6 +189,23 @@ static int cbsegm_ldpc_select_ls(uint32_t Kp, uint32_t K_b, uint32_t* Z_c, uint8 return SRSLTE_ERROR; } +/** + * @brief Calculate the transport block (TB) CRC length for LDPC based shared + * + * @remark Implemented according to TS 38.212 V15.9.0 7.2.1 Transport block CRC attachment + * + * @param tbs Transport block size + * @return The TB CRC length L + */ +static uint32_t srslte_cbsegm_ldpc_L(uint32_t tbs) +{ + if (tbs <= 3824) { + return 16; + } + + return 24; +} + static int srslte_cbsegm_ldpc(srslte_cbsegm_t* s, srslte_basegraph_t bg, uint32_t tbs) { // Check input pointer @@ -200,11 +219,14 @@ static int srslte_cbsegm_ldpc(srslte_cbsegm_t* s, srslte_basegraph_t bg, uint32_ return SRSLTE_SUCCESS; } + // Calculate TB CRC length + uint32_t L = srslte_cbsegm_ldpc_L(tbs); + // Select maximum code block size uint32_t K_cb = (bg == BG1) ? SRSLTE_LDPC_BG1_MAX_LEN_CB : SRSLTE_LDPC_BG2_MAX_LEN_CB; // Calculate CB sizes - uint32_t B = tbs + 24; + uint32_t B = tbs + L; uint32_t C = 0; uint32_t Bp = 0; cbsegm_cb_size(B, K_cb, &C, &Bp); @@ -235,11 +257,14 @@ static int srslte_cbsegm_ldpc(srslte_cbsegm_t* s, srslte_basegraph_t bg, uint32_ // Save segmentation s->tbs = tbs; + s->L_tb = L; + s->L_cb = C > 1 ? 24 : 0; s->C = C; s->F = K * C; s->C1 = C; s->K1 = K; s->K1_idx = i_ls; + s->Z = Z_c; // Only one CB size is used s->C2 = 0; diff --git a/lib/src/phy/fec/ldpc/ldpc_rm.c b/lib/src/phy/fec/ldpc/ldpc_rm.c index 0312e56a6..c8ecaba80 100644 --- a/lib/src/phy/fec/ldpc/ldpc_rm.c +++ b/lib/src/phy/fec/ldpc/ldpc_rm.c @@ -61,12 +61,6 @@ static const uint32_t BASEN[2] = {66, 50}; */ static const uint32_t BASEK[2] = {22, 10}; -/*! - * \brief Look-up table: Retuns the mod order associated to a srslte_mod_t - * - */ -static const uint32_t MODORD[5] = {1, 2, 4, 6, 8}; - /*! * \brief Look-up table: Maximum number of coded bits available for transmission in a * transport block @@ -130,7 +124,7 @@ static int init_rm(srslte_ldpc_rm_t* p, } uint32_t basek0 = BASEK0[rv][bg]; - uint32_t mod_order = MODORD[mod_type]; + uint32_t mod_order = srslte_mod_bits_x_symbol(mod_type); uint32_t N = ls * BASEN[bg]; uint32_t K = ls * BASEK[bg];