diff --git a/lib/include/srslte/phy/fec/convolutional/convcoder.h b/lib/include/srslte/phy/fec/convolutional/convcoder.h index f3b57d8ca..faa2298a2 100644 --- a/lib/include/srslte/phy/fec/convolutional/convcoder.h +++ b/lib/include/srslte/phy/fec/convolutional/convcoder.h @@ -32,8 +32,8 @@ #ifndef SRSLTE_CONVCODER_H #define SRSLTE_CONVCODER_H -#include "../../../../../../../../../../usr/lib/gcc/x86_64-linux-gnu/7/include/stdbool.h" -#include "../../../config.h" +#include "srslte/config.h" +#include typedef struct SRSLTE_API { uint32_t R; diff --git a/lib/include/srslte/phy/fec/convolutional/rm_conv.h b/lib/include/srslte/phy/fec/convolutional/rm_conv.h index 490c6361e..2e626ad94 100644 --- a/lib/include/srslte/phy/fec/convolutional/rm_conv.h +++ b/lib/include/srslte/phy/fec/convolutional/rm_conv.h @@ -31,7 +31,7 @@ #ifndef SRSLTE_RM_CONV_H #define SRSLTE_RM_CONV_H -#include "../../../config.h" +#include "srslte/config.h" #ifndef SRSLTE_RX_NULL #define SRSLTE_RX_NULL 10000 diff --git a/lib/include/srslte/phy/fec/convolutional/viterbi.h b/lib/include/srslte/phy/fec/convolutional/viterbi.h index 7bf402ed6..753976997 100644 --- a/lib/include/srslte/phy/fec/convolutional/viterbi.h +++ b/lib/include/srslte/phy/fec/convolutional/viterbi.h @@ -20,7 +20,7 @@ */ /****************************************************************************** - * File: convolutional.h + * File: viterbi.h * * Description: Viterbi decoder for convolutionally encoded data. * Used for decoding of PBCH and PDCCH (type 37 decoder). @@ -31,8 +31,8 @@ #ifndef SRSLTE_VITERBI_H #define SRSLTE_VITERBI_H -#include "../../../../../../../../../../usr/lib/gcc/x86_64-linux-gnu/7/include/stdbool.h" -#include "../../../config.h" +#include "srslte/config.h" +#include typedef enum { SRSLTE_VITERBI_27 = 0, SRSLTE_VITERBI_29, SRSLTE_VITERBI_37, SRSLTE_VITERBI_39 } srslte_viterbi_type_t; diff --git a/lib/include/srslte/phy/fec/turbo/rm_turbo.h b/lib/include/srslte/phy/fec/turbo/rm_turbo.h index b06fdb53a..b6b774f81 100644 --- a/lib/include/srslte/phy/fec/turbo/rm_turbo.h +++ b/lib/include/srslte/phy/fec/turbo/rm_turbo.h @@ -31,7 +31,7 @@ #define SRSLTE_RM_TURBO_H #include "srslte/config.h" -#include "srslte/phy/fec/turbodecoder.h" +#include "srslte/phy/fec/turbo/turbodecoder.h" #ifndef SRSLTE_RX_NULL #define SRSLTE_RX_NULL 10000 diff --git a/lib/include/srslte/phy/fec/turbo/turbocoder.h b/lib/include/srslte/phy/fec/turbo/turbocoder.h index b00a75f8e..b8802f9f3 100644 --- a/lib/include/srslte/phy/fec/turbo/turbocoder.h +++ b/lib/include/srslte/phy/fec/turbo/turbocoder.h @@ -17,56 +17,55 @@ * the LICENSE file in the top-level directory of this distribution * and at http://www.gnu.org/licenses/. * - */ - -/********************************************************************************************** - * File: turbocoder.h - * - * Description: Turbo coder. - * Parallel Concatenated Convolutional Code (PCCC) with two 8-state constituent - * encoders and one turbo code internal interleaver. The coding rate of turbo - * encoder is 1/3. - * - * Reference: 3GPP TS 36.212 version 10.0.0 Release 10 Sec. 5.1.3.2 - *********************************************************************************************/ - -#ifndef SRSLTE_TURBOCODER_H -#define SRSLTE_TURBOCODER_H - -#include "srslte/config.h" -#include "srslte/phy/fec/crc.h" -#include "srslte/phy/fec/tc_interl.h" - -#define SRSLTE_TCOD_MAX_LEN_CB_BYTES (6144 / 8) - -#ifndef SRSLTE_TX_NULL -#define SRSLTE_TX_NULL 100 -#endif - -typedef struct SRSLTE_API { - uint32_t max_long_cb; - uint8_t* temp; -} srslte_tcod_t; - -/* This structure is used as an output for the LUT version of the encoder. - * The encoder produces parity bits only and rate matching will interleave them - * with the systematic bits - */ - -SRSLTE_API int srslte_tcod_init(srslte_tcod_t* h, uint32_t max_long_cb); - -SRSLTE_API void srslte_tcod_free(srslte_tcod_t* h); - -SRSLTE_API int srslte_tcod_encode(srslte_tcod_t* h, uint8_t* input, uint8_t* output, uint32_t long_cb); - -SRSLTE_API int srslte_tcod_encode_lut(srslte_tcod_t* h, - srslte_crc_t* crc_tb, - srslte_crc_t* crc_cb, - uint8_t* input, - uint8_t* parity, - uint32_t cblen_idx, - bool last_cb); - -SRSLTE_API void srslte_tcod_gentable(); - -#endif // SRSLTE_TURBOCODER_H + */ + +/********************************************************************************************** + * File: turbocoder.h + * + * Description: Turbo coder. + * Parallel Concatenated Convolutional Code (PCCC) with two 8-state constituent + * encoders and one turbo code internal interleaver. The coding rate of turbo + * encoder is 1/3. + * + * Reference: 3GPP TS 36.212 version 10.0.0 Release 10 Sec. 5.1.3.2 + *********************************************************************************************/ + +#ifndef SRSLTE_TURBOCODER_H +#define SRSLTE_TURBOCODER_H + +#include "srslte/config.h" +#include "srslte/phy/fec/crc.h" +#include "srslte/phy/fec/turbo/tc_interl.h" +#define SRSLTE_TCOD_MAX_LEN_CB_BYTES (6144 / 8) + +#ifndef SRSLTE_TX_NULL +#define SRSLTE_TX_NULL 100 +#endif + +typedef struct SRSLTE_API { + uint32_t max_long_cb; + uint8_t* temp; +} srslte_tcod_t; + +/* This structure is used as an output for the LUT version of the encoder. + * The encoder produces parity bits only and rate matching will interleave them + * with the systematic bits + */ + +SRSLTE_API int srslte_tcod_init(srslte_tcod_t* h, uint32_t max_long_cb); + +SRSLTE_API void srslte_tcod_free(srslte_tcod_t* h); + +SRSLTE_API int srslte_tcod_encode(srslte_tcod_t* h, uint8_t* input, uint8_t* output, uint32_t long_cb); + +SRSLTE_API int srslte_tcod_encode_lut(srslte_tcod_t* h, + srslte_crc_t* crc_tb, + srslte_crc_t* crc_cb, + uint8_t* input, + uint8_t* parity, + uint32_t cblen_idx, + bool last_cb); + +SRSLTE_API void srslte_tcod_gentable(); + +#endif // SRSLTE_TURBOCODER_H diff --git a/lib/include/srslte/phy/fec/turbo/turbodecoder.h b/lib/include/srslte/phy/fec/turbo/turbodecoder.h index ab02b7595..213853868 100644 --- a/lib/include/srslte/phy/fec/turbo/turbodecoder.h +++ b/lib/include/srslte/phy/fec/turbo/turbodecoder.h @@ -35,8 +35,8 @@ #define SRSLTE_TURBODECODER_H #include "srslte/config.h" -#include "srslte/phy/fec/cbsegm.h" -#include "srslte/phy/fec/tc_interl.h" +#include "srslte/phy/fec/turbo/cbsegm.h" +#include "srslte/phy/fec/turbo/tc_interl.h" #define SRSLTE_TCOD_RATE 3 #define SRSLTE_TCOD_TOTALTAIL 12 @@ -48,11 +48,11 @@ // Include interfaces for 8 and 16 bit decoder implementations #define LLR_IS_8BIT -#include "srslte/phy/fec/turbodecoder_impl.h" +#include "srslte/phy/fec/turbo/turbodecoder_impl.h" #undef LLR_IS_8BIT #define LLR_IS_16BIT -#include "srslte/phy/fec/turbodecoder_impl.h" +#include "srslte/phy/fec/turbo/turbodecoder_impl.h" #undef LLR_IS_16BIT #define SRSLTE_TDEC_NOF_AUTO_MODES_8 2 diff --git a/lib/include/srslte/phy/fec/turbo/turbodecoder_gen.h b/lib/include/srslte/phy/fec/turbo/turbodecoder_gen.h index b62958377..d5fcfecde 100644 --- a/lib/include/srslte/phy/fec/turbo/turbodecoder_gen.h +++ b/lib/include/srslte/phy/fec/turbo/turbodecoder_gen.h @@ -35,9 +35,8 @@ #define SRSLTE_TURBODECODER_GEN_H #include "srslte/config.h" -#include "srslte/phy/fec/cbsegm.h" -#include "srslte/phy/fec/tc_interl.h" - +#include "srslte/phy/fec/turbo/cbsegm.h" +#include "srslte/phy/fec/turbo/tc_interl.h" #define SRSLTE_TCOD_RATE 3 #define SRSLTE_TCOD_TOTALTAIL 12 diff --git a/lib/include/srslte/phy/phch/npbch.h b/lib/include/srslte/phy/phch/npbch.h index 8dc5e3788..9db41efc9 100644 --- a/lib/include/srslte/phy/phch/npbch.h +++ b/lib/include/srslte/phy/phch/npbch.h @@ -25,10 +25,10 @@ #include "srslte/config.h" #include "srslte/phy/common/phy_common.h" -#include "srslte/phy/fec/convcoder.h" +#include "srslte/phy/fec/convolutional/convcoder.h" +#include "srslte/phy/fec/convolutional/rm_conv.h" +#include "srslte/phy/fec/convolutional/viterbi.h" #include "srslte/phy/fec/crc.h" -#include "srslte/phy/fec/rm_conv.h" -#include "srslte/phy/fec/viterbi.h" #include "srslte/phy/mimo/layermap.h" #include "srslte/phy/mimo/precoding.h" #include "srslte/phy/modem/demod_soft.h" diff --git a/lib/include/srslte/phy/phch/npdcch.h b/lib/include/srslte/phy/phch/npdcch.h index f67fa76ba..f65c24253 100644 --- a/lib/include/srslte/phy/phch/npdcch.h +++ b/lib/include/srslte/phy/phch/npdcch.h @@ -24,10 +24,10 @@ #include "srslte/config.h" #include "srslte/phy/common/phy_common.h" -#include "srslte/phy/fec/convcoder.h" +#include "srslte/phy/fec/convolutional/convcoder.h" +#include "srslte/phy/fec/convolutional/rm_conv.h" +#include "srslte/phy/fec/convolutional/viterbi.h" #include "srslte/phy/fec/crc.h" -#include "srslte/phy/fec/rm_conv.h" -#include "srslte/phy/fec/viterbi.h" #include "srslte/phy/mimo/layermap.h" #include "srslte/phy/mimo/precoding.h" #include "srslte/phy/modem/demod_soft.h" diff --git a/lib/include/srslte/phy/phch/npdsch.h b/lib/include/srslte/phy/phch/npdsch.h index eeb37398b..c9bf61b3b 100644 --- a/lib/include/srslte/phy/phch/npdsch.h +++ b/lib/include/srslte/phy/phch/npdsch.h @@ -24,7 +24,7 @@ #include "srslte/config.h" #include "srslte/phy/common/phy_common.h" -#include "srslte/phy/fec/convcoder.h" +#include "srslte/phy/fec/convolutional/convcoder.h" #include "srslte/phy/fec/crc.h" #include "srslte/phy/mimo/layermap.h" #include "srslte/phy/mimo/precoding.h" diff --git a/lib/include/srslte/phy/phch/pbch.h b/lib/include/srslte/phy/phch/pbch.h index 8597ba7ca..e8742d331 100644 --- a/lib/include/srslte/phy/phch/pbch.h +++ b/lib/include/srslte/phy/phch/pbch.h @@ -35,10 +35,10 @@ #include "srslte/config.h" #include "srslte/phy/ch_estimation/chest_dl.h" #include "srslte/phy/common/phy_common.h" -#include "srslte/phy/fec/convcoder.h" +#include "srslte/phy/fec/convolutional/convcoder.h" +#include "srslte/phy/fec/convolutional/rm_conv.h" +#include "srslte/phy/fec/convolutional/viterbi.h" #include "srslte/phy/fec/crc.h" -#include "srslte/phy/fec/rm_conv.h" -#include "srslte/phy/fec/viterbi.h" #include "srslte/phy/mimo/layermap.h" #include "srslte/phy/mimo/precoding.h" #include "srslte/phy/modem/demod_soft.h" diff --git a/lib/include/srslte/phy/phch/pdcch.h b/lib/include/srslte/phy/phch/pdcch.h index 45bad2255..45815c93e 100644 --- a/lib/include/srslte/phy/phch/pdcch.h +++ b/lib/include/srslte/phy/phch/pdcch.h @@ -33,10 +33,10 @@ #include "srslte/config.h" #include "srslte/phy/ch_estimation/chest_dl.h" #include "srslte/phy/common/phy_common.h" -#include "srslte/phy/fec/convcoder.h" +#include "srslte/phy/fec/convolutional/convcoder.h" +#include "srslte/phy/fec/convolutional/rm_conv.h" +#include "srslte/phy/fec/convolutional/viterbi.h" #include "srslte/phy/fec/crc.h" -#include "srslte/phy/fec/rm_conv.h" -#include "srslte/phy/fec/viterbi.h" #include "srslte/phy/mimo/layermap.h" #include "srslte/phy/mimo/precoding.h" #include "srslte/phy/modem/demod_soft.h" diff --git a/lib/include/srslte/phy/phch/pdsch_cfg.h b/lib/include/srslte/phy/phch/pdsch_cfg.h index 08fb5d2b0..6fdb4b423 100644 --- a/lib/include/srslte/phy/phch/pdsch_cfg.h +++ b/lib/include/srslte/phy/phch/pdsch_cfg.h @@ -30,8 +30,8 @@ #ifndef SRSLTE_PDSCH_CFG_H #define SRSLTE_PDSCH_CFG_H -#include "srslte/phy/fec/cbsegm.h" #include "srslte/phy/fec/softbuffer.h" +#include "srslte/phy/fec/turbo/cbsegm.h" #include "srslte/phy/phch/ra.h" typedef struct SRSLTE_API { diff --git a/lib/include/srslte/phy/phch/psbch.h b/lib/include/srslte/phy/phch/psbch.h index 41a98394b..ae99bd871 100644 --- a/lib/include/srslte/phy/phch/psbch.h +++ b/lib/include/srslte/phy/phch/psbch.h @@ -22,14 +22,14 @@ #ifndef SRSLTE_PSBCH_H #define SRSLTE_PSBCH_H -#include -#include -#include -#include -#include -#include -#include -#include +#include "srslte/phy/common/phy_common_sl.h" +#include "srslte/phy/dft/dft_precoding.h" +#include "srslte/phy/fec/convolutional/convcoder.h" +#include "srslte/phy/fec/convolutional/viterbi.h" +#include "srslte/phy/fec/crc.h" +#include "srslte/phy/modem/demod_soft.h" +#include "srslte/phy/modem/modem_table.h" +#include "srslte/phy/scrambling/scrambling.h" #define SRSLTE_SL_BCH_CRC_LEN 16 diff --git a/lib/include/srslte/phy/phch/pscch.h b/lib/include/srslte/phy/phch/pscch.h index f14685d0e..765d5d43e 100644 --- a/lib/include/srslte/phy/phch/pscch.h +++ b/lib/include/srslte/phy/phch/pscch.h @@ -27,9 +27,9 @@ #include "srslte/phy/common/phy_common_sl.h" #include "srslte/phy/common/sequence.h" #include "srslte/phy/dft/dft_precoding.h" -#include "srslte/phy/fec/convcoder.h" +#include "srslte/phy/fec/convolutional/convcoder.h" +#include "srslte/phy/fec/convolutional/viterbi.h" #include "srslte/phy/fec/crc.h" -#include "srslte/phy/fec/viterbi.h" #include "srslte/phy/modem/modem_table.h" /** diff --git a/lib/include/srslte/phy/phch/pssch.h b/lib/include/srslte/phy/phch/pssch.h index ee6cabf2c..371caf4fa 100644 --- a/lib/include/srslte/phy/phch/pssch.h +++ b/lib/include/srslte/phy/phch/pssch.h @@ -25,8 +25,8 @@ #include "srslte/phy/common/phy_common_sl.h" #include "srslte/phy/dft/dft_precoding.h" #include "srslte/phy/fec/crc.h" -#include "srslte/phy/fec/turbocoder.h" -#include "srslte/phy/fec/turbodecoder.h" +#include "srslte/phy/fec/turbo/turbocoder.h" +#include "srslte/phy/fec/turbo/turbodecoder.h" #include "srslte/phy/modem/mod.h" #include "srslte/phy/scrambling/scrambling.h" diff --git a/lib/include/srslte/phy/phch/sch.h b/lib/include/srslte/phy/phch/sch.h index aff76f7bd..7f6d31d98 100644 --- a/lib/include/srslte/phy/phch/sch.h +++ b/lib/include/srslte/phy/phch/sch.h @@ -33,9 +33,9 @@ #include "srslte/config.h" #include "srslte/phy/common/phy_common.h" #include "srslte/phy/fec/crc.h" -#include "srslte/phy/fec/rm_turbo.h" -#include "srslte/phy/fec/turbocoder.h" -#include "srslte/phy/fec/turbodecoder.h" +#include "srslte/phy/fec/turbo/rm_turbo.h" +#include "srslte/phy/fec/turbo/turbocoder.h" +#include "srslte/phy/fec/turbo/turbodecoder.h" #include "srslte/phy/phch/pdsch_cfg.h" #include "srslte/phy/phch/pusch_cfg.h" #include "srslte/phy/phch/uci.h" diff --git a/lib/include/srslte/phy/phch/uci.h b/lib/include/srslte/phy/phch/uci.h index ab9c366f7..81011884c 100644 --- a/lib/include/srslte/phy/phch/uci.h +++ b/lib/include/srslte/phy/phch/uci.h @@ -32,8 +32,8 @@ #include "srslte/config.h" #include "srslte/phy/common/phy_common.h" +#include "srslte/phy/fec/convolutional/viterbi.h" #include "srslte/phy/fec/crc.h" -#include "srslte/phy/fec/viterbi.h" #include "srslte/phy/phch/pusch_cfg.h" #include "srslte/phy/phch/uci_cfg.h" diff --git a/lib/include/srslte/srslte.h b/lib/include/srslte/srslte.h index 7dbd36323..aef12345b 100644 --- a/lib/include/srslte/srslte.h +++ b/lib/include/srslte/srslte.h @@ -58,19 +58,18 @@ extern "C" { #include "srslte/phy/channel/ch_awgn.h" -#include "srslte/phy/fec/cbsegm.h" -#include "srslte/phy/fec/convcoder.h" -#include "srslte/phy/fec/crc.h" -#include "srslte/phy/fec/rm_conv.h" -#include "srslte/phy/fec/rm_turbo.h" -#include "srslte/phy/fec/tc_interl.h" -#include "srslte/phy/fec/turbocoder.h" -#include "srslte/phy/fec/turbodecoder.h" -#include "srslte/phy/fec/viterbi.h" - #include "srslte/phy/dft/dft.h" #include "srslte/phy/dft/dft_precoding.h" #include "srslte/phy/dft/ofdm.h" +#include "srslte/phy/fec/convolutional/convcoder.h" +#include "srslte/phy/fec/convolutional/rm_conv.h" +#include "srslte/phy/fec/convolutional/viterbi.h" +#include "srslte/phy/fec/crc.h" +#include "srslte/phy/fec/turbo/cbsegm.h" +#include "srslte/phy/fec/turbo/rm_turbo.h" +#include "srslte/phy/fec/turbo/tc_interl.h" +#include "srslte/phy/fec/turbo/turbocoder.h" +#include "srslte/phy/fec/turbo/turbodecoder.h" #include "srslte/phy/io/binsource.h" #include "srslte/phy/io/filesink.h" diff --git a/lib/src/phy/fec/CMakeLists.txt b/lib/src/phy/fec/CMakeLists.txt index 77a0a7465..7f219d0f8 100644 --- a/lib/src/phy/fec/CMakeLists.txt +++ b/lib/src/phy/fec/CMakeLists.txt @@ -18,6 +18,12 @@ # and at http://www.gnu.org/licenses/. # -file(GLOB SOURCES "*.c") -add_library(srslte_fec OBJECT ${SOURCES}) +set(FEC_SOURCES + crc.c + softbuffer.c) + add_subdirectory(test) +add_subdirectory(convolutional) +add_subdirectory(turbo) + +add_library(srslte_fec OBJECT ${FEC_SOURCES}) diff --git a/lib/src/phy/fec/convolutional/convcoder.c b/lib/src/phy/fec/convolutional/convcoder.c index f40369a5c..d58e3759b 100644 --- a/lib/src/phy/fec/convolutional/convcoder.c +++ b/lib/src/phy/fec/convolutional/convcoder.c @@ -25,7 +25,7 @@ #include #include "parity.h" -#include "srslte/phy/fec/convcoder.h" +#include "srslte/phy/fec/convolutional/convcoder.h" /** * Convolution encodes according to given parameters. diff --git a/lib/src/phy/fec/turbo/parity.c b/lib/src/phy/fec/convolutional/parity.c similarity index 100% rename from lib/src/phy/fec/turbo/parity.c rename to lib/src/phy/fec/convolutional/parity.c diff --git a/lib/src/phy/fec/turbo/parity.h b/lib/src/phy/fec/convolutional/parity.h similarity index 100% rename from lib/src/phy/fec/turbo/parity.h rename to lib/src/phy/fec/convolutional/parity.h diff --git a/lib/src/phy/fec/convolutional/viterbi.c b/lib/src/phy/fec/convolutional/viterbi.c index 80de2c938..443862fae 100644 --- a/lib/src/phy/fec/convolutional/viterbi.c +++ b/lib/src/phy/fec/convolutional/viterbi.c @@ -26,8 +26,8 @@ #include #include -#include "../parity.h" -#include "srslte/phy/fec/viterbi.h" +#include "parity.h" +#include "srslte/phy/fec/convolutional/viterbi.h" #include "srslte/phy/utils/debug.h" #include "srslte/phy/utils/vector.h" #include "viterbi37.h" diff --git a/lib/src/phy/fec/convolutional/viterbi37_avx2.c b/lib/src/phy/fec/convolutional/viterbi37_avx2.c index b22afe186..0749bfdf4 100644 --- a/lib/src/phy/fec/convolutional/viterbi37_avx2.c +++ b/lib/src/phy/fec/convolutional/viterbi37_avx2.c @@ -5,7 +5,7 @@ * May be used under the terms of the GNU Lesser General Public License (LGPL) */ -#include "../parity.h" +#include "parity.h" #include #include #include diff --git a/lib/src/phy/fec/convolutional/viterbi37_avx2_16bit.c b/lib/src/phy/fec/convolutional/viterbi37_avx2_16bit.c index c80250fc8..9f0aaabaa 100644 --- a/lib/src/phy/fec/convolutional/viterbi37_avx2_16bit.c +++ b/lib/src/phy/fec/convolutional/viterbi37_avx2_16bit.c @@ -5,7 +5,7 @@ * May be used under the terms of the GNU Lesser General Public License (LGPL) */ -#include "../parity.h" +#include "parity.h" #include #include #include diff --git a/lib/src/phy/fec/convolutional/viterbi37_neon.c b/lib/src/phy/fec/convolutional/viterbi37_neon.c index e39cd2492..9de1540ae 100644 --- a/lib/src/phy/fec/convolutional/viterbi37_neon.c +++ b/lib/src/phy/fec/convolutional/viterbi37_neon.c @@ -5,7 +5,7 @@ * May be used under the terms of the GNU Lesser General Public License (LGPL) */ -#include "../parity.h" +#include "parity.h" #include #include #include diff --git a/lib/src/phy/fec/convolutional/viterbi37_port.c b/lib/src/phy/fec/convolutional/viterbi37_port.c index 7c53d4927..122dfd188 100644 --- a/lib/src/phy/fec/convolutional/viterbi37_port.c +++ b/lib/src/phy/fec/convolutional/viterbi37_port.c @@ -8,7 +8,7 @@ #include #include -#include "../parity.h" +#include "parity.h" #include "viterbi37.h" #include #include diff --git a/lib/src/phy/fec/convolutional/viterbi37_sse.c b/lib/src/phy/fec/convolutional/viterbi37_sse.c index 0c48f8bd6..2730c8c01 100644 --- a/lib/src/phy/fec/convolutional/viterbi37_sse.c +++ b/lib/src/phy/fec/convolutional/viterbi37_sse.c @@ -5,7 +5,7 @@ * May be used under the terms of the GNU Lesser General Public License (LGPL) */ -#include "../parity.h" +#include "parity.h" #include #include #include diff --git a/lib/src/phy/fec/softbuffer.c b/lib/src/phy/fec/softbuffer.c index db85c4926..5db39e83d 100644 --- a/lib/src/phy/fec/softbuffer.c +++ b/lib/src/phy/fec/softbuffer.c @@ -19,21 +19,16 @@ * */ -#include -#include #include #include #include #include -#include #include #include "srslte/phy/common/phy_common.h" -#include "srslte/phy/fec/rm_turbo.h" #include "srslte/phy/fec/softbuffer.h" -#include "srslte/phy/fec/turbodecoder_gen.h" +#include "srslte/phy/fec/turbo/turbodecoder_gen.h" #include "srslte/phy/phch/ra.h" -#include "srslte/phy/utils/debug.h" #include "srslte/phy/utils/vector.h" #define MAX_PDSCH_RE(cp) (2 * SRSLTE_CP_NSYMB(cp) * 12) diff --git a/lib/src/phy/fec/test/CMakeLists.txt b/lib/src/phy/fec/test/CMakeLists.txt index 566212f01..5da43bf38 100644 --- a/lib/src/phy/fec/test/CMakeLists.txt +++ b/lib/src/phy/fec/test/CMakeLists.txt @@ -18,57 +18,6 @@ # and at http://www.gnu.org/licenses/. # - -######################################################################## -# RATEMATCHING TEST -######################################################################## - -add_executable(rm_conv_test rm_conv_test.c) -target_link_libraries(rm_conv_test srslte_phy) - -add_executable(rm_turbo_test rm_turbo_test.c) -target_link_libraries(rm_turbo_test srslte_phy) - -add_test(rm_conv_test_1 rm_conv_test -t 480 -r 1920) -add_test(rm_conv_test_2 rm_conv_test -t 1920 -r 480) - -add_test(rm_turbo_test_1 rm_turbo_test -e 1920) -add_test(rm_turbo_test_2 rm_turbo_test -e 8192) - -######################################################################## -# Turbo Coder TEST -######################################################################## -add_executable(turbodecoder_test turbodecoder_test.c) -target_link_libraries(turbodecoder_test srslte_phy) - -add_test(turbodecoder_test_504_1 turbodecoder_test -n 100 -s 1 -l 504 -e 1.0 -t) -add_test(turbodecoder_test_504_2 turbodecoder_test -n 100 -s 1 -l 504 -e 2.0 -t) -add_test(turbodecoder_test_6114_1_5 turbodecoder_test -n 100 -s 1 -l 6144 -e 1.5 -t) -add_test(turbodecoder_test_known turbodecoder_test -n 1 -s 1 -k -e 0.5) - -add_executable(turbocoder_test turbocoder_test.c) -target_link_libraries(turbocoder_test srslte_phy) -add_test(turbocoder_test_all turbocoder_test) - -######################################################################## -# Viterbi TEST -######################################################################## - -add_executable(viterbi_test viterbi_test.c) -target_link_libraries(viterbi_test srslte_phy) - -add_test(viterbi_40_0 viterbi_test -n 1000 -s 1 -l 40 -t -e 0.0) -add_test(viterbi_40_2 viterbi_test -n 1000 -s 1 -l 40 -t -e 2.0) -add_test(viterbi_40_3 viterbi_test -n 1000 -s 1 -l 40 -t -e 3.0) -add_test(viterbi_40_4 viterbi_test -n 1000 -s 1 -l 40 -t -e 4.5) - -add_test(viterbi_1000_0 viterbi_test -n 100 -s 1 -l 1000 -t -e 0.0) -add_test(viterbi_1000_2 viterbi_test -n 100 -s 1 -l 1000 -t -e 2.0) -add_test(viterbi_1000_3 viterbi_test -n 100 -s 1 -l 1000 -t -e 3.0) -add_test(viterbi_1000_4 viterbi_test -n 100 -s 1 -l 1000 -t -e 4.5) - -add_test(viterbi_56_4 viterbi_test -n 1000 -s 1 -l 56 -t -e 4.5) - ######################################################################## # CRC TEST ######################################################################## diff --git a/lib/src/phy/fec/turbo/cbsegm.c b/lib/src/phy/fec/turbo/cbsegm.c index f7cdc5348..978c1c38d 100644 --- a/lib/src/phy/fec/turbo/cbsegm.c +++ b/lib/src/phy/fec/turbo/cbsegm.c @@ -22,8 +22,8 @@ #include #include -#include "srslte/phy/fec/cbsegm.h" -#include "srslte/phy/fec/turbodecoder_gen.h" +#include "srslte/phy/fec/turbo/cbsegm.h" +#include "srslte/phy/fec/turbo/turbodecoder_gen.h" #include "srslte/phy/utils/debug.h" const uint32_t tc_cb_sizes[SRSLTE_NOF_TC_CB_SIZES] = { diff --git a/lib/src/phy/fec/turbo/rm_conv.c b/lib/src/phy/fec/turbo/rm_conv.c index 97fed1960..d044a7881 100644 --- a/lib/src/phy/fec/turbo/rm_conv.c +++ b/lib/src/phy/fec/turbo/rm_conv.c @@ -23,7 +23,7 @@ #include #include -#include "srslte/phy/fec/rm_conv.h" +#include "srslte/phy/fec/convolutional/rm_conv.h" #include "srslte/phy/utils/debug.h" #define NCOLS 32 diff --git a/lib/src/phy/fec/turbo/rm_turbo.c b/lib/src/phy/fec/turbo/rm_turbo.c index 3107ac3ae..848288c68 100644 --- a/lib/src/phy/fec/turbo/rm_turbo.c +++ b/lib/src/phy/fec/turbo/rm_turbo.c @@ -26,8 +26,8 @@ #include #include -#include "srslte/phy/fec/cbsegm.h" -#include "srslte/phy/fec/rm_turbo.h" +#include "srslte/phy/fec/turbo/cbsegm.h" +#include "srslte/phy/fec/turbo/rm_turbo.h" #include "srslte/phy/utils/bit.h" #include "srslte/phy/utils/debug.h" #include "srslte/phy/utils/vector.h" diff --git a/lib/src/phy/fec/turbo/tc_interl_lte.c b/lib/src/phy/fec/turbo/tc_interl_lte.c index 5189f83e0..a4975953e 100644 --- a/lib/src/phy/fec/turbo/tc_interl_lte.c +++ b/lib/src/phy/fec/turbo/tc_interl_lte.c @@ -17,93 +17,93 @@ * the LICENSE file in the top-level directory of this distribution * and at http://www.gnu.org/licenses/. * - */ - -#include -#include -#include - -#include "srslte/phy/common/phy_common.h" -#include "srslte/phy/fec/cbsegm.h" -#include "srslte/phy/fec/tc_interl.h" -#include "srslte/phy/fec/turbocoder.h" -#include "srslte/phy/utils/debug.h" -#include "srslte/phy/utils/vector.h" - -/************************************************ - * - * LTE TURBO CODE INTERLEAVER - * - ************************************************/ - -const uint32_t f1_list[SRSLTE_NOF_TC_CB_SIZES] = { - 3, 7, 19, 7, 7, 11, 5, 11, 7, 41, 103, 15, 9, 17, 9, 21, 101, 21, 57, 23, 13, - 27, 11, 27, 85, 29, 33, 15, 17, 33, 103, 19, 19, 37, 19, 21, 21, 115, 193, 21, 133, 81, - 45, 23, 243, 151, 155, 25, 51, 47, 91, 29, 29, 247, 29, 89, 91, 157, 55, 31, 17, 35, 227, - 65, 19, 37, 41, 39, 185, 43, 21, 155, 79, 139, 23, 217, 25, 17, 127, 25, 239, 17, 137, 215, - 29, 15, 147, 29, 59, 65, 55, 31, 17, 171, 67, 35, 19, 39, 19, 199, 21, 211, 21, 43, 149, - 45, 49, 71, 13, 17, 25, 183, 55, 127, 27, 29, 29, 57, 45, 31, 59, 185, 113, 31, 17, 171, - 209, 253, 367, 265, 181, 39, 27, 127, 143, 43, 29, 45, 157, 47, 13, 111, 443, 51, 51, 451, 257, - 57, 313, 271, 179, 331, 363, 375, 127, 31, 33, 43, 33, 477, 35, 233, 357, 337, 37, 71, 71, 37, - 39, 127, 39, 39, 31, 113, 41, 251, 43, 21, 43, 45, 45, 161, 89, 323, 47, 23, 47, 263}; - -const uint32_t f2_list[SRSLTE_NOF_TC_CB_SIZES] = { - 10, 12, 42, 16, 18, 20, 22, 24, 26, 84, 90, 32, 34, 108, 38, 120, 84, 44, 46, 48, 50, - 52, 36, 56, 58, 60, 62, 32, 198, 68, 210, 36, 74, 76, 78, 120, 82, 84, 86, 44, 90, 46, - 94, 48, 98, 40, 102, 52, 106, 72, 110, 168, 114, 58, 118, 180, 122, 62, 84, 64, 66, 68, 420, - 96, 74, 76, 234, 80, 82, 252, 86, 44, 120, 92, 94, 48, 98, 80, 102, 52, 106, 48, 110, 112, - 114, 58, 118, 60, 122, 124, 84, 64, 66, 204, 140, 72, 74, 76, 78, 240, 82, 252, 86, 88, 60, - 92, 846, 48, 28, 80, 102, 104, 954, 96, 110, 112, 114, 116, 354, 120, 610, 124, 420, 64, 66, 136, - 420, 216, 444, 456, 468, 80, 164, 504, 172, 88, 300, 92, 188, 96, 28, 240, 204, 104, 212, 192, 220, - 336, 228, 232, 236, 120, 244, 248, 168, 64, 130, 264, 134, 408, 138, 280, 142, 480, 146, 444, 120, 152, - 462, 234, 158, 80, 96, 902, 166, 336, 170, 86, 174, 176, 178, 120, 182, 184, 186, 94, 190, 480}; - -int srslte_tc_interl_LTE_gen(srslte_tc_interl_t* h, uint32_t long_cb) -{ - return srslte_tc_interl_LTE_gen_interl(h, long_cb, 1); -} - -#define deinter(x, win) ((x % (long_cb / win)) * (win) + x / (long_cb / win)) -#define inter(x, win) ((x % win) * (long_cb / win) + x / win) - -int srslte_tc_interl_LTE_gen_interl(srslte_tc_interl_t* h, uint32_t long_cb, uint32_t interl_win) -{ - uint32_t cb_table_idx, f1, f2; - uint64_t i, j; - - if (long_cb > h->max_long_cb) { - ERROR("Interleaver initiated for max_long_cb=%d\n", h->max_long_cb); - return -1; - } - - cb_table_idx = srslte_cbsegm_cbindex(long_cb); - if (cb_table_idx == -1) { - ERROR("Can't find long_cb=%d in valid TC CB table\n", long_cb); - return -1; - } - - f1 = f1_list[cb_table_idx]; - f2 = f2_list[cb_table_idx]; - - h->forward[0] = 0; - h->reverse[0] = 0; - for (i = 1; i < long_cb; i++) { - j = (f1 * i + f2 * i * i) % (long_cb); - h->forward[i] = (uint32_t)j; - h->reverse[j] = (uint32_t)i; - } - if (interl_win != 1) { - uint16_t* f = srslte_vec_u16_malloc(long_cb); - uint16_t* r = srslte_vec_u16_malloc(long_cb); - memcpy(f, h->forward, long_cb * sizeof(uint16_t)); - memcpy(r, h->reverse, long_cb * sizeof(uint16_t)); - for (i = 0; i < long_cb; i++) { - h->forward[i] = deinter(f[inter(i, interl_win)], interl_win); - h->reverse[i] = deinter(r[inter(i, interl_win)], interl_win); - } - free(f); - free(r); - } - - return 0; -} + */ + +#include +#include +#include + +#include "srslte/phy/common/phy_common.h" +#include "srslte/phy/fec/turbo/cbsegm.h" +#include "srslte/phy/fec/turbo/tc_interl.h" +#include "srslte/phy/fec/turbo/turbocoder.h" +#include "srslte/phy/utils/debug.h" +#include "srslte/phy/utils/vector.h" + +/************************************************ + * + * LTE TURBO CODE INTERLEAVER + * + ************************************************/ + +const uint32_t f1_list[SRSLTE_NOF_TC_CB_SIZES] = { + 3, 7, 19, 7, 7, 11, 5, 11, 7, 41, 103, 15, 9, 17, 9, 21, 101, 21, 57, 23, 13, + 27, 11, 27, 85, 29, 33, 15, 17, 33, 103, 19, 19, 37, 19, 21, 21, 115, 193, 21, 133, 81, + 45, 23, 243, 151, 155, 25, 51, 47, 91, 29, 29, 247, 29, 89, 91, 157, 55, 31, 17, 35, 227, + 65, 19, 37, 41, 39, 185, 43, 21, 155, 79, 139, 23, 217, 25, 17, 127, 25, 239, 17, 137, 215, + 29, 15, 147, 29, 59, 65, 55, 31, 17, 171, 67, 35, 19, 39, 19, 199, 21, 211, 21, 43, 149, + 45, 49, 71, 13, 17, 25, 183, 55, 127, 27, 29, 29, 57, 45, 31, 59, 185, 113, 31, 17, 171, + 209, 253, 367, 265, 181, 39, 27, 127, 143, 43, 29, 45, 157, 47, 13, 111, 443, 51, 51, 451, 257, + 57, 313, 271, 179, 331, 363, 375, 127, 31, 33, 43, 33, 477, 35, 233, 357, 337, 37, 71, 71, 37, + 39, 127, 39, 39, 31, 113, 41, 251, 43, 21, 43, 45, 45, 161, 89, 323, 47, 23, 47, 263}; + +const uint32_t f2_list[SRSLTE_NOF_TC_CB_SIZES] = { + 10, 12, 42, 16, 18, 20, 22, 24, 26, 84, 90, 32, 34, 108, 38, 120, 84, 44, 46, 48, 50, + 52, 36, 56, 58, 60, 62, 32, 198, 68, 210, 36, 74, 76, 78, 120, 82, 84, 86, 44, 90, 46, + 94, 48, 98, 40, 102, 52, 106, 72, 110, 168, 114, 58, 118, 180, 122, 62, 84, 64, 66, 68, 420, + 96, 74, 76, 234, 80, 82, 252, 86, 44, 120, 92, 94, 48, 98, 80, 102, 52, 106, 48, 110, 112, + 114, 58, 118, 60, 122, 124, 84, 64, 66, 204, 140, 72, 74, 76, 78, 240, 82, 252, 86, 88, 60, + 92, 846, 48, 28, 80, 102, 104, 954, 96, 110, 112, 114, 116, 354, 120, 610, 124, 420, 64, 66, 136, + 420, 216, 444, 456, 468, 80, 164, 504, 172, 88, 300, 92, 188, 96, 28, 240, 204, 104, 212, 192, 220, + 336, 228, 232, 236, 120, 244, 248, 168, 64, 130, 264, 134, 408, 138, 280, 142, 480, 146, 444, 120, 152, + 462, 234, 158, 80, 96, 902, 166, 336, 170, 86, 174, 176, 178, 120, 182, 184, 186, 94, 190, 480}; + +int srslte_tc_interl_LTE_gen(srslte_tc_interl_t* h, uint32_t long_cb) +{ + return srslte_tc_interl_LTE_gen_interl(h, long_cb, 1); +} + +#define deinter(x, win) ((x % (long_cb / win)) * (win) + x / (long_cb / win)) +#define inter(x, win) ((x % win) * (long_cb / win) + x / win) + +int srslte_tc_interl_LTE_gen_interl(srslte_tc_interl_t* h, uint32_t long_cb, uint32_t interl_win) +{ + uint32_t cb_table_idx, f1, f2; + uint64_t i, j; + + if (long_cb > h->max_long_cb) { + ERROR("Interleaver initiated for max_long_cb=%d\n", h->max_long_cb); + return -1; + } + + cb_table_idx = srslte_cbsegm_cbindex(long_cb); + if (cb_table_idx == -1) { + ERROR("Can't find long_cb=%d in valid TC CB table\n", long_cb); + return -1; + } + + f1 = f1_list[cb_table_idx]; + f2 = f2_list[cb_table_idx]; + + h->forward[0] = 0; + h->reverse[0] = 0; + for (i = 1; i < long_cb; i++) { + j = (f1 * i + f2 * i * i) % (long_cb); + h->forward[i] = (uint32_t)j; + h->reverse[j] = (uint32_t)i; + } + if (interl_win != 1) { + uint16_t* f = srslte_vec_u16_malloc(long_cb); + uint16_t* r = srslte_vec_u16_malloc(long_cb); + memcpy(f, h->forward, long_cb * sizeof(uint16_t)); + memcpy(r, h->reverse, long_cb * sizeof(uint16_t)); + for (i = 0; i < long_cb; i++) { + h->forward[i] = deinter(f[inter(i, interl_win)], interl_win); + h->reverse[i] = deinter(r[inter(i, interl_win)], interl_win); + } + free(f); + free(r); + } + + return 0; +} diff --git a/lib/src/phy/fec/turbo/tc_interl_umts.c b/lib/src/phy/fec/turbo/tc_interl_umts.c index a518291df..d5c62be8e 100644 --- a/lib/src/phy/fec/turbo/tc_interl_umts.c +++ b/lib/src/phy/fec/turbo/tc_interl_umts.c @@ -17,250 +17,250 @@ * the LICENSE file in the top-level directory of this distribution * and at http://www.gnu.org/licenses/. * - */ - -#include -#include -#include -#include - -#include "srslte/phy/fec/tc_interl.h" -#include "srslte/phy/utils/debug.h" -#include "srslte/phy/utils/vector.h" - -#define TURBO_SRSLTE_TCOD_RATE 3 - -uint32_t mcd(uint32_t x, uint32_t y); - -/************************************************ - * - * UMTS TURBO CODE INTERLEAVER - * - ************************************************/ - -#define MAX_ROWS 20 -#define MAX_COLS 256 - -const unsigned short table_p[52] = {7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, - 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, - 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, - 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257}; -const uint8_t table_v[52] = {3, 2, 2, 3, 2, 5, 2, 3, 2, 6, 3, 5, 2, 2, 2, 2, 7, 5, 3, 2, 3, 5, 2, 5, 2, 6, - 3, 3, 2, 3, 2, 2, 6, 5, 2, 5, 2, 2, 2, 19, 5, 2, 3, 2, 3, 2, 6, 3, 7, 7, 6, 3}; - -int srslte_tc_interl_init(srslte_tc_interl_t* h, uint32_t max_long_cb) -{ - int ret = -1; - h->forward = srslte_vec_u16_malloc(max_long_cb); - if (!h->forward) { - perror("malloc"); - goto clean_exit; - } - h->reverse = srslte_vec_u16_malloc(max_long_cb); - if (!h->reverse) { - perror("malloc"); - goto clean_exit; - } - h->max_long_cb = max_long_cb; - ret = 0; -clean_exit: - if (ret == -1) { - srslte_tc_interl_free(h); - } - return ret; -} - -void srslte_tc_interl_free(srslte_tc_interl_t* h) -{ - if (h->forward) { - free(h->forward); - } - if (h->reverse) { - free(h->reverse); - } - bzero(h, sizeof(srslte_tc_interl_t)); -} - -int srslte_tc_interl_UMTS_gen(srslte_tc_interl_t* h, uint32_t long_cb) -{ - - uint32_t i, j; - uint32_t res, prim, aux; - uint32_t kp, k; - uint16_t *per, *desper; - uint8_t v; - uint16_t p; - uint16_t s[MAX_COLS], q[MAX_ROWS], r[MAX_ROWS], T[MAX_ROWS]; - uint16_t U[MAX_COLS * MAX_ROWS]; - uint32_t M_Rows, M_Cols, M_long; - - M_long = long_cb; - - if (long_cb > h->max_long_cb) { - ERROR("Interleaver initiated for max_long_cb=%d\n", h->max_long_cb); - return -1; - } - - /* Find R*/ - if ((40 <= M_long) && (M_long <= 159)) - M_Rows = 5; - else if (((160 <= M_long) && (M_long <= 200)) || ((481 <= M_long) && (M_long <= 530))) - M_Rows = 10; - else - M_Rows = 20; - - /* Find p i v*/ - if ((481 <= M_long) && (M_long <= 530)) { - p = 53; - v = 2; - M_Cols = p; - } else { - i = 0; - do { - p = table_p[i]; - v = table_v[i]; - i++; - } while (M_long > (M_Rows * (p + 1))); - } - - /* Find C*/ - if ((M_long) <= (M_Rows) * ((p)-1)) - M_Cols = (p)-1; - else if (((M_Rows) * (p - 1) < M_long) && (M_long <= (M_Rows) * (p))) - M_Cols = p; - else if ((M_Rows) * (p) < M_long) - M_Cols = (p) + 1; - - q[0] = 1; - prim = 6; - - for (i = 1; i < M_Rows; i++) { - do { - prim++; - res = mcd(prim, p - 1); - } while (res != 1); - q[i] = prim; - } - - s[0] = 1; - for (i = 1; i < p - 1; i++) { - s[i] = (v * s[i - 1]) % p; - } - - if (M_long <= 159 && M_long >= 40) { - T[0] = 4; - T[1] = 3; - T[2] = 2; - T[3] = 1; - T[4] = 0; - } else if ((M_long <= 200 && M_long >= 160) || (M_long <= 530 && M_long >= 481)) { - T[0] = 9; - T[1] = 8; - T[2] = 7; - T[3] = 6; - T[4] = 5; - T[5] = 4; - T[6] = 3; - T[7] = 2; - T[8] = 1; - T[9] = 0; - } else if ((M_long <= 2480 && M_long >= 2281) || (M_long <= 3210 && M_long >= 3161)) { - T[0] = 19; - T[1] = 9; - T[2] = 14; - T[3] = 4; - T[4] = 0; - T[5] = 2; - T[6] = 5; - T[7] = 7; - T[8] = 12; - T[9] = 18; - T[10] = 16; - T[11] = 13; - T[12] = 17; - T[13] = 15; - T[14] = 3; - T[15] = 1; - T[16] = 6; - T[17] = 11; - T[18] = 8; - T[19] = 10; - } else { - T[0] = 19; - T[1] = 9; - T[2] = 14; - T[3] = 4; - T[4] = 0; - T[5] = 2; - T[6] = 5; - T[7] = 7; - T[8] = 12; - T[9] = 18; - T[10] = 10; - T[11] = 8; - T[12] = 13; - T[13] = 17; - T[14] = 3; - T[15] = 1; - T[16] = 16; - T[17] = 6; - T[18] = 15; - T[19] = 11; - } - - for (i = 0; i < M_Rows; i++) { - r[T[i]] = q[i]; - } - - for (i = 0; i < M_Rows; i++) { - for (j = 0; j < p - 1; j++) { - U[i * M_Cols + j] = s[(j * r[i]) % (p - 1)]; - if (M_Cols == (p - 1)) - U[i * M_Cols + j] -= 1; - } - } - - if (M_Cols == p) { - for (i = 0; i < M_Rows; i++) - U[i * M_Cols + p - 1] = 0; - } else if (M_Cols == p + 1) { - for (i = 0; i < M_Rows; i++) { - U[i * M_Cols + p - 1] = 0; - U[i * M_Cols + p] = p; - } - if (M_long == M_Cols * M_Rows) { - aux = U[(M_Rows - 1) * M_Cols + p]; - U[(M_Rows - 1) * M_Cols + p] = U[(M_Rows - 1) * M_Cols + 0]; - U[(M_Rows - 1) * M_Cols + 0] = aux; - } - } - - per = h->forward; - desper = h->reverse; - - k = 0; - for (j = 0; j < M_Cols; j++) { - for (i = 0; i < M_Rows; i++) { - kp = T[i] * M_Cols + U[i * M_Cols + j]; - if (kp < M_long) { - desper[kp] = k; - per[k] = kp; - k++; - } - } - } - - return 0; -} - -uint32_t mcd(uint32_t x, uint32_t y) -{ - uint32_t r = 1; - - while (r) { - r = x % y; - x = y; - y = r; - } - return x; -} + */ + +#include +#include +#include +#include + +#include "srslte/phy/fec/turbo/tc_interl.h" +#include "srslte/phy/utils/debug.h" +#include "srslte/phy/utils/vector.h" + +#define TURBO_SRSLTE_TCOD_RATE 3 + +uint32_t mcd(uint32_t x, uint32_t y); + +/************************************************ + * + * UMTS TURBO CODE INTERLEAVER + * + ************************************************/ + +#define MAX_ROWS 20 +#define MAX_COLS 256 + +const unsigned short table_p[52] = {7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, + 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, + 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, + 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257}; +const uint8_t table_v[52] = {3, 2, 2, 3, 2, 5, 2, 3, 2, 6, 3, 5, 2, 2, 2, 2, 7, 5, 3, 2, 3, 5, 2, 5, 2, 6, + 3, 3, 2, 3, 2, 2, 6, 5, 2, 5, 2, 2, 2, 19, 5, 2, 3, 2, 3, 2, 6, 3, 7, 7, 6, 3}; + +int srslte_tc_interl_init(srslte_tc_interl_t* h, uint32_t max_long_cb) +{ + int ret = -1; + h->forward = srslte_vec_u16_malloc(max_long_cb); + if (!h->forward) { + perror("malloc"); + goto clean_exit; + } + h->reverse = srslte_vec_u16_malloc(max_long_cb); + if (!h->reverse) { + perror("malloc"); + goto clean_exit; + } + h->max_long_cb = max_long_cb; + ret = 0; +clean_exit: + if (ret == -1) { + srslte_tc_interl_free(h); + } + return ret; +} + +void srslte_tc_interl_free(srslte_tc_interl_t* h) +{ + if (h->forward) { + free(h->forward); + } + if (h->reverse) { + free(h->reverse); + } + bzero(h, sizeof(srslte_tc_interl_t)); +} + +int srslte_tc_interl_UMTS_gen(srslte_tc_interl_t* h, uint32_t long_cb) +{ + + uint32_t i, j; + uint32_t res, prim, aux; + uint32_t kp, k; + uint16_t *per, *desper; + uint8_t v; + uint16_t p; + uint16_t s[MAX_COLS], q[MAX_ROWS], r[MAX_ROWS], T[MAX_ROWS]; + uint16_t U[MAX_COLS * MAX_ROWS]; + uint32_t M_Rows, M_Cols, M_long; + + M_long = long_cb; + + if (long_cb > h->max_long_cb) { + ERROR("Interleaver initiated for max_long_cb=%d\n", h->max_long_cb); + return -1; + } + + /* Find R*/ + if ((40 <= M_long) && (M_long <= 159)) + M_Rows = 5; + else if (((160 <= M_long) && (M_long <= 200)) || ((481 <= M_long) && (M_long <= 530))) + M_Rows = 10; + else + M_Rows = 20; + + /* Find p i v*/ + if ((481 <= M_long) && (M_long <= 530)) { + p = 53; + v = 2; + M_Cols = p; + } else { + i = 0; + do { + p = table_p[i]; + v = table_v[i]; + i++; + } while (M_long > (M_Rows * (p + 1))); + } + + /* Find C*/ + if ((M_long) <= (M_Rows) * ((p)-1)) + M_Cols = (p)-1; + else if (((M_Rows) * (p - 1) < M_long) && (M_long <= (M_Rows) * (p))) + M_Cols = p; + else if ((M_Rows) * (p) < M_long) + M_Cols = (p) + 1; + + q[0] = 1; + prim = 6; + + for (i = 1; i < M_Rows; i++) { + do { + prim++; + res = mcd(prim, p - 1); + } while (res != 1); + q[i] = prim; + } + + s[0] = 1; + for (i = 1; i < p - 1; i++) { + s[i] = (v * s[i - 1]) % p; + } + + if (M_long <= 159 && M_long >= 40) { + T[0] = 4; + T[1] = 3; + T[2] = 2; + T[3] = 1; + T[4] = 0; + } else if ((M_long <= 200 && M_long >= 160) || (M_long <= 530 && M_long >= 481)) { + T[0] = 9; + T[1] = 8; + T[2] = 7; + T[3] = 6; + T[4] = 5; + T[5] = 4; + T[6] = 3; + T[7] = 2; + T[8] = 1; + T[9] = 0; + } else if ((M_long <= 2480 && M_long >= 2281) || (M_long <= 3210 && M_long >= 3161)) { + T[0] = 19; + T[1] = 9; + T[2] = 14; + T[3] = 4; + T[4] = 0; + T[5] = 2; + T[6] = 5; + T[7] = 7; + T[8] = 12; + T[9] = 18; + T[10] = 16; + T[11] = 13; + T[12] = 17; + T[13] = 15; + T[14] = 3; + T[15] = 1; + T[16] = 6; + T[17] = 11; + T[18] = 8; + T[19] = 10; + } else { + T[0] = 19; + T[1] = 9; + T[2] = 14; + T[3] = 4; + T[4] = 0; + T[5] = 2; + T[6] = 5; + T[7] = 7; + T[8] = 12; + T[9] = 18; + T[10] = 10; + T[11] = 8; + T[12] = 13; + T[13] = 17; + T[14] = 3; + T[15] = 1; + T[16] = 16; + T[17] = 6; + T[18] = 15; + T[19] = 11; + } + + for (i = 0; i < M_Rows; i++) { + r[T[i]] = q[i]; + } + + for (i = 0; i < M_Rows; i++) { + for (j = 0; j < p - 1; j++) { + U[i * M_Cols + j] = s[(j * r[i]) % (p - 1)]; + if (M_Cols == (p - 1)) + U[i * M_Cols + j] -= 1; + } + } + + if (M_Cols == p) { + for (i = 0; i < M_Rows; i++) + U[i * M_Cols + p - 1] = 0; + } else if (M_Cols == p + 1) { + for (i = 0; i < M_Rows; i++) { + U[i * M_Cols + p - 1] = 0; + U[i * M_Cols + p] = p; + } + if (M_long == M_Cols * M_Rows) { + aux = U[(M_Rows - 1) * M_Cols + p]; + U[(M_Rows - 1) * M_Cols + p] = U[(M_Rows - 1) * M_Cols + 0]; + U[(M_Rows - 1) * M_Cols + 0] = aux; + } + } + + per = h->forward; + desper = h->reverse; + + k = 0; + for (j = 0; j < M_Cols; j++) { + for (i = 0; i < M_Rows; i++) { + kp = T[i] * M_Cols + U[i * M_Cols + j]; + if (kp < M_long) { + desper[kp] = k; + per[k] = kp; + k++; + } + } + } + + return 0; +} + +uint32_t mcd(uint32_t x, uint32_t y) +{ + uint32_t r = 1; + + while (r) { + r = x % y; + x = y; + y = r; + } + return x; +} diff --git a/lib/src/phy/fec/turbo/turbocoder.c b/lib/src/phy/fec/turbo/turbocoder.c index ee0edb664..05384f3d7 100644 --- a/lib/src/phy/fec/turbo/turbocoder.c +++ b/lib/src/phy/fec/turbo/turbocoder.c @@ -17,410 +17,410 @@ * the LICENSE file in the top-level directory of this distribution * and at http://www.gnu.org/licenses/. * - */ - -#include -#include -#include -#include - -#include "srslte/phy/fec/cbsegm.h" -#include "srslte/phy/fec/turbocoder.h" -#include "srslte/phy/utils/bit.h" -#include "srslte/phy/utils/debug.h" -#include "srslte/phy/utils/vector.h" - -#define NOF_REGS 3 - -#define RATE 3 -#define TOTALTAIL 12 - -typedef struct { - uint8_t next_state; - uint8_t output; -} tcod_lut_t; - -static tcod_lut_t tcod_lut[8][256]; -static uint16_t tcod_per_fw[188][6144]; -static srslte_bit_interleaver_t tcod_interleavers[188]; - -static bool table_initiated = false; - -int srslte_tcod_init(srslte_tcod_t* h, uint32_t max_long_cb) -{ - - h->max_long_cb = max_long_cb; - h->temp = srslte_vec_malloc(max_long_cb / 8); - - if (!table_initiated) { - table_initiated = true; - srslte_tcod_gentable(); - } - return 0; -} - -void srslte_tcod_free(srslte_tcod_t* h) -{ - h->max_long_cb = 0; - if (h->temp) { - free(h->temp); - } - - if (table_initiated) { - for (int i = 0; i < 188; i++) { - srslte_bit_interleaver_free(&tcod_interleavers[i]); - } - table_initiated = false; - } -} - -/* Expects bits (1 byte = 1 bit) and produces bits. The systematic and parity bits are interlaced in the output */ -int srslte_tcod_encode(srslte_tcod_t* h, uint8_t* input, uint8_t* output, uint32_t long_cb) -{ - - uint8_t reg1_0, reg1_1, reg1_2, reg2_0, reg2_1, reg2_2; - uint32_t i, k = 0, j; - uint8_t bit; - uint8_t in, out; - uint16_t* per; - - if (long_cb > h->max_long_cb) { - ERROR("Turbo coder initiated for max_long_cb=%d\n", h->max_long_cb); - return -1; - } - - int longcb_idx = srslte_cbsegm_cbindex(long_cb); - if (longcb_idx < 0) { - ERROR("Invalid CB size %d\n", long_cb); - return -1; - } - - per = tcod_per_fw[longcb_idx]; - - reg1_0 = 0; - reg1_1 = 0; - reg1_2 = 0; - - reg2_0 = 0; - reg2_1 = 0; - reg2_2 = 0; - - k = 0; - for (i = 0; i < long_cb; i++) { - if (input[i] == SRSLTE_TX_NULL) { - bit = 0; - } else { - bit = input[i]; - } - output[k] = input[i]; - - k++; - - in = bit ^ (reg1_2 ^ reg1_1); - out = reg1_2 ^ (reg1_0 ^ in); - - reg1_2 = reg1_1; - reg1_1 = reg1_0; - reg1_0 = in; - - if (input[i] == SRSLTE_TX_NULL) { - output[k] = SRSLTE_TX_NULL; - } else { - output[k] = out; - } - k++; - - bit = input[per[i]]; - if (bit == SRSLTE_TX_NULL) { - bit = 0; - } - - in = bit ^ (reg2_2 ^ reg2_1); - out = reg2_2 ^ (reg2_0 ^ in); - - reg2_2 = reg2_1; - reg2_1 = reg2_0; - reg2_0 = in; - - output[k] = out; - k++; - } - - k = 3 * long_cb; - - /* TAILING CODER #1 */ - for (j = 0; j < NOF_REGS; j++) { - bit = reg1_2 ^ reg1_1; - - output[k] = bit; - k++; - - in = bit ^ (reg1_2 ^ reg1_1); - out = reg1_2 ^ (reg1_0 ^ in); - - reg1_2 = reg1_1; - reg1_1 = reg1_0; - reg1_0 = in; - - output[k] = out; - k++; - } - - /* TAILING CODER #2 */ - for (j = 0; j < NOF_REGS; j++) { - bit = reg2_2 ^ reg2_1; - - output[k] = bit; - k++; - - in = bit ^ (reg2_2 ^ reg2_1); - out = reg2_2 ^ (reg2_0 ^ in); - - reg2_2 = reg2_1; - reg2_1 = reg2_0; - reg2_0 = in; - - output[k] = out; - k++; - } - return 0; -} - -/* Expects bytes and produces bytes. The systematic and parity bits are interlaced in the output */ -int srslte_tcod_encode_lut(srslte_tcod_t* h, - srslte_crc_t* crc_tb, - srslte_crc_t* crc_cb, - uint8_t* input, - uint8_t* parity, - uint32_t cblen_idx, - bool last_cb) -{ - if (cblen_idx < 188) { - uint32_t long_cb = (uint32_t)srslte_cbsegm_cbsize(cblen_idx); - - if (long_cb % 8) { - ERROR("Turbo coder LUT implementation long_cb must be multiple of 8\n"); - return -1; - } - - /* Reset CRC */ - if (crc_cb) { - srslte_crc_set_init(crc_cb, 0); - } - - /* Parity bits for the 1st constituent encoders */ - uint8_t state0 = 0; - if (crc_cb) { - int block_size_nocrc = (long_cb - crc_cb->order - ((last_cb) ? crc_tb->order : 0)) / 8; - - /* if CRC pointer is given */ - for (int i = 0; i < block_size_nocrc; i++) { - uint8_t in = input[i]; - - /* Put byte in TB CRC and save latest checksum */ - srslte_crc_checksum_put_byte(crc_tb, in); - - /* Put byte in CB CRC and save latest checksum */ - srslte_crc_checksum_put_byte(crc_cb, in); - - /* Run actual encoder */ - tcod_lut_t l = tcod_lut[state0][in]; - parity[i] = l.output; - state0 = l.next_state; - } - - if (last_cb) { - uint32_t checksum = (uint32_t)srslte_crc_checksum_get(crc_tb); - for (int i = 0; i < crc_tb->order / 8; i++) { - int mask_shift = 8 * (crc_tb->order / 8 - i - 1); - int idx = block_size_nocrc + i; - uint8_t in = (uint8_t)((checksum >> mask_shift) & 0xff); - - /* Put byte in CB CRC and save latest checksum */ - srslte_crc_checksum_put_byte(crc_cb, in); - - input[idx] = in; - tcod_lut_t l = tcod_lut[state0][in]; - parity[idx] = l.output; - state0 = l.next_state; - } - } - - uint32_t checksum = (uint32_t)srslte_crc_checksum_get(crc_cb); - for (int i = 0; i < crc_cb->order / 8; i++) { - int mask_shift = 8 * (crc_cb->order / 8 - i - 1); - int idx = (long_cb - crc_cb->order) / 8 + i; - uint8_t in = (uint8_t)((checksum >> mask_shift) & 0xff); - - input[idx] = in; - tcod_lut_t l = tcod_lut[state0][in]; - parity[idx] = l.output; - state0 = l.next_state; - } - - } else { - /* No CRC given */ - int block_size_nocrc = (long_cb - ((last_cb) ? crc_tb->order : 0)) / 8; - - for (uint32_t i = 0; i < block_size_nocrc; i++) { - uint8_t in = input[i]; - - srslte_crc_checksum_put_byte(crc_tb, in); - - tcod_lut_t l = tcod_lut[state0][in]; - parity[i] = l.output; - state0 = l.next_state; - } - - if (last_cb) { - uint32_t checksum = (uint32_t)srslte_crc_checksum_get(crc_tb); - for (int i = 0; i < crc_tb->order / 8; i++) { - int mask_shift = 8 * (crc_tb->order / 8 - i - 1); - int idx = block_size_nocrc + i; - uint8_t in = (uint8_t)((checksum >> mask_shift) & 0xff); - - input[idx] = in; - tcod_lut_t l = tcod_lut[state0][in]; - parity[idx] = l.output; - state0 = l.next_state; - } - } - } - parity[long_cb / 8] = 0; // will put tail here later - - /* Interleave input */ - srslte_bit_interleaver_run(&tcod_interleavers[cblen_idx], input, h->temp, 0); - // srslte_bit_interleave(input, h->temp, tcod_per_fw[cblen_idx], long_cb); - - /* Parity bits for the 2nd constituent encoders */ - uint8_t state1 = 0; - for (uint32_t i = 0; i < long_cb / 8; i++) { - tcod_lut_t l = tcod_lut[state1][h->temp[i]]; - uint8_t out = l.output; - parity[long_cb / 8 + i] |= (out & 0xf0) >> 4; - parity[long_cb / 8 + i + 1] = (out & 0xf) << 4; - state1 = l.next_state; - } - - /* Tail bits */ - uint8_t reg1_0, reg1_1, reg1_2, reg2_0, reg2_1, reg2_2; - uint8_t bit, in, out; - uint8_t k = 0; - uint8_t tail[12]; - - reg2_0 = (state1 & 4) >> 2; - reg2_1 = (state1 & 2) >> 1; - reg2_2 = state1 & 1; - - reg1_0 = (state0 & 4) >> 2; - reg1_1 = (state0 & 2) >> 1; - reg1_2 = state0 & 1; - - /* TAILING CODER #1 */ - for (uint32_t j = 0; j < NOF_REGS; j++) { - bit = reg1_2 ^ reg1_1; - - tail[k] = bit; - k++; - - in = bit ^ (reg1_2 ^ reg1_1); - out = reg1_2 ^ (reg1_0 ^ in); - - reg1_2 = reg1_1; - reg1_1 = reg1_0; - reg1_0 = in; - - tail[k] = out; - k++; - } - - /* TAILING CODER #2 */ - for (uint32_t j = 0; j < NOF_REGS; j++) { - bit = reg2_2 ^ reg2_1; - - tail[k] = bit; - k++; - - in = bit ^ (reg2_2 ^ reg2_1); - out = reg2_2 ^ (reg2_0 ^ in); - - reg2_2 = reg2_1; - reg2_1 = reg2_0; - reg2_0 = in; - - tail[k] = out; - k++; - } - - uint8_t tailv[3][4]; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 3; j++) { - tailv[j][i] = tail[3 * i + j]; - } - } - uint8_t* x = tailv[0]; - input[long_cb / 8] = (srslte_bit_pack(&x, 4) << 4); - x = tailv[1]; - parity[long_cb / 8] |= (srslte_bit_pack(&x, 4) << 4); - x = tailv[2]; - parity[2 * long_cb / 8] |= (srslte_bit_pack(&x, 4) & 0xf); - - return 3 * long_cb + TOTALTAIL; - } else { - return -1; - } -} - -void srslte_tcod_gentable() -{ - srslte_tc_interl_t interl; - - if (srslte_tc_interl_init(&interl, 6144)) { - ERROR("Error initiating interleave\n"); - return; - } - - for (uint32_t len = 0; len < 188; len++) { - uint32_t long_cb = srslte_cbsegm_cbsize(len); - if (srslte_tc_interl_LTE_gen(&interl, long_cb)) { - ERROR("Error initiating TC interleaver for long_cb=%d\n", long_cb); - return; - } - // Save fw/bw permutation tables - for (uint32_t i = 0; i < long_cb; i++) { - tcod_per_fw[len][i] = interl.forward[i]; - } - srslte_bit_interleaver_init(&tcod_interleavers[len], tcod_per_fw[len], long_cb); - for (uint32_t i = long_cb; i < 6144; i++) { - tcod_per_fw[len][i] = 0; - } - } - // Compute state transitions - for (uint32_t state = 0; state < 8; state++) { - for (uint32_t data = 0; data < 256; data++) { - - uint8_t reg_0, reg_1, reg_2; - reg_0 = (state & 4) >> 2; - reg_1 = (state & 2) >> 1; - reg_2 = state & 1; - - tcod_lut[state][data].output = 0; - uint8_t bit, in, out; - for (uint32_t i = 0; i < 8; i++) { - bit = (data & (1 << (7 - i))) ? 1 : 0; - - in = bit ^ (reg_2 ^ reg_1); - out = reg_2 ^ (reg_0 ^ in); - - reg_2 = reg_1; - reg_1 = reg_0; - reg_0 = in; - - tcod_lut[state][data].output |= out << (7 - i); - } - tcod_lut[state][data].next_state = (uint8_t)((reg_0 << 2 | reg_1 << 1 | reg_2) % 8); - } - } - - srslte_tc_interl_free(&interl); -} + */ + +#include +#include +#include +#include + +#include "srslte/phy/fec/turbo/cbsegm.h" +#include "srslte/phy/fec/turbo/turbocoder.h" +#include "srslte/phy/utils/bit.h" +#include "srslte/phy/utils/debug.h" +#include "srslte/phy/utils/vector.h" + +#define NOF_REGS 3 + +#define RATE 3 +#define TOTALTAIL 12 + +typedef struct { + uint8_t next_state; + uint8_t output; +} tcod_lut_t; + +static tcod_lut_t tcod_lut[8][256]; +static uint16_t tcod_per_fw[188][6144]; +static srslte_bit_interleaver_t tcod_interleavers[188]; + +static bool table_initiated = false; + +int srslte_tcod_init(srslte_tcod_t* h, uint32_t max_long_cb) +{ + + h->max_long_cb = max_long_cb; + h->temp = srslte_vec_malloc(max_long_cb / 8); + + if (!table_initiated) { + table_initiated = true; + srslte_tcod_gentable(); + } + return 0; +} + +void srslte_tcod_free(srslte_tcod_t* h) +{ + h->max_long_cb = 0; + if (h->temp) { + free(h->temp); + } + + if (table_initiated) { + for (int i = 0; i < 188; i++) { + srslte_bit_interleaver_free(&tcod_interleavers[i]); + } + table_initiated = false; + } +} + +/* Expects bits (1 byte = 1 bit) and produces bits. The systematic and parity bits are interlaced in the output */ +int srslte_tcod_encode(srslte_tcod_t* h, uint8_t* input, uint8_t* output, uint32_t long_cb) +{ + + uint8_t reg1_0, reg1_1, reg1_2, reg2_0, reg2_1, reg2_2; + uint32_t i, k = 0, j; + uint8_t bit; + uint8_t in, out; + uint16_t* per; + + if (long_cb > h->max_long_cb) { + ERROR("Turbo coder initiated for max_long_cb=%d\n", h->max_long_cb); + return -1; + } + + int longcb_idx = srslte_cbsegm_cbindex(long_cb); + if (longcb_idx < 0) { + ERROR("Invalid CB size %d\n", long_cb); + return -1; + } + + per = tcod_per_fw[longcb_idx]; + + reg1_0 = 0; + reg1_1 = 0; + reg1_2 = 0; + + reg2_0 = 0; + reg2_1 = 0; + reg2_2 = 0; + + k = 0; + for (i = 0; i < long_cb; i++) { + if (input[i] == SRSLTE_TX_NULL) { + bit = 0; + } else { + bit = input[i]; + } + output[k] = input[i]; + + k++; + + in = bit ^ (reg1_2 ^ reg1_1); + out = reg1_2 ^ (reg1_0 ^ in); + + reg1_2 = reg1_1; + reg1_1 = reg1_0; + reg1_0 = in; + + if (input[i] == SRSLTE_TX_NULL) { + output[k] = SRSLTE_TX_NULL; + } else { + output[k] = out; + } + k++; + + bit = input[per[i]]; + if (bit == SRSLTE_TX_NULL) { + bit = 0; + } + + in = bit ^ (reg2_2 ^ reg2_1); + out = reg2_2 ^ (reg2_0 ^ in); + + reg2_2 = reg2_1; + reg2_1 = reg2_0; + reg2_0 = in; + + output[k] = out; + k++; + } + + k = 3 * long_cb; + + /* TAILING CODER #1 */ + for (j = 0; j < NOF_REGS; j++) { + bit = reg1_2 ^ reg1_1; + + output[k] = bit; + k++; + + in = bit ^ (reg1_2 ^ reg1_1); + out = reg1_2 ^ (reg1_0 ^ in); + + reg1_2 = reg1_1; + reg1_1 = reg1_0; + reg1_0 = in; + + output[k] = out; + k++; + } + + /* TAILING CODER #2 */ + for (j = 0; j < NOF_REGS; j++) { + bit = reg2_2 ^ reg2_1; + + output[k] = bit; + k++; + + in = bit ^ (reg2_2 ^ reg2_1); + out = reg2_2 ^ (reg2_0 ^ in); + + reg2_2 = reg2_1; + reg2_1 = reg2_0; + reg2_0 = in; + + output[k] = out; + k++; + } + return 0; +} + +/* Expects bytes and produces bytes. The systematic and parity bits are interlaced in the output */ +int srslte_tcod_encode_lut(srslte_tcod_t* h, + srslte_crc_t* crc_tb, + srslte_crc_t* crc_cb, + uint8_t* input, + uint8_t* parity, + uint32_t cblen_idx, + bool last_cb) +{ + if (cblen_idx < 188) { + uint32_t long_cb = (uint32_t)srslte_cbsegm_cbsize(cblen_idx); + + if (long_cb % 8) { + ERROR("Turbo coder LUT implementation long_cb must be multiple of 8\n"); + return -1; + } + + /* Reset CRC */ + if (crc_cb) { + srslte_crc_set_init(crc_cb, 0); + } + + /* Parity bits for the 1st constituent encoders */ + uint8_t state0 = 0; + if (crc_cb) { + int block_size_nocrc = (long_cb - crc_cb->order - ((last_cb) ? crc_tb->order : 0)) / 8; + + /* if CRC pointer is given */ + for (int i = 0; i < block_size_nocrc; i++) { + uint8_t in = input[i]; + + /* Put byte in TB CRC and save latest checksum */ + srslte_crc_checksum_put_byte(crc_tb, in); + + /* Put byte in CB CRC and save latest checksum */ + srslte_crc_checksum_put_byte(crc_cb, in); + + /* Run actual encoder */ + tcod_lut_t l = tcod_lut[state0][in]; + parity[i] = l.output; + state0 = l.next_state; + } + + if (last_cb) { + uint32_t checksum = (uint32_t)srslte_crc_checksum_get(crc_tb); + for (int i = 0; i < crc_tb->order / 8; i++) { + int mask_shift = 8 * (crc_tb->order / 8 - i - 1); + int idx = block_size_nocrc + i; + uint8_t in = (uint8_t)((checksum >> mask_shift) & 0xff); + + /* Put byte in CB CRC and save latest checksum */ + srslte_crc_checksum_put_byte(crc_cb, in); + + input[idx] = in; + tcod_lut_t l = tcod_lut[state0][in]; + parity[idx] = l.output; + state0 = l.next_state; + } + } + + uint32_t checksum = (uint32_t)srslte_crc_checksum_get(crc_cb); + for (int i = 0; i < crc_cb->order / 8; i++) { + int mask_shift = 8 * (crc_cb->order / 8 - i - 1); + int idx = (long_cb - crc_cb->order) / 8 + i; + uint8_t in = (uint8_t)((checksum >> mask_shift) & 0xff); + + input[idx] = in; + tcod_lut_t l = tcod_lut[state0][in]; + parity[idx] = l.output; + state0 = l.next_state; + } + + } else { + /* No CRC given */ + int block_size_nocrc = (long_cb - ((last_cb) ? crc_tb->order : 0)) / 8; + + for (uint32_t i = 0; i < block_size_nocrc; i++) { + uint8_t in = input[i]; + + srslte_crc_checksum_put_byte(crc_tb, in); + + tcod_lut_t l = tcod_lut[state0][in]; + parity[i] = l.output; + state0 = l.next_state; + } + + if (last_cb) { + uint32_t checksum = (uint32_t)srslte_crc_checksum_get(crc_tb); + for (int i = 0; i < crc_tb->order / 8; i++) { + int mask_shift = 8 * (crc_tb->order / 8 - i - 1); + int idx = block_size_nocrc + i; + uint8_t in = (uint8_t)((checksum >> mask_shift) & 0xff); + + input[idx] = in; + tcod_lut_t l = tcod_lut[state0][in]; + parity[idx] = l.output; + state0 = l.next_state; + } + } + } + parity[long_cb / 8] = 0; // will put tail here later + + /* Interleave input */ + srslte_bit_interleaver_run(&tcod_interleavers[cblen_idx], input, h->temp, 0); + // srslte_bit_interleave(input, h->temp, tcod_per_fw[cblen_idx], long_cb); + + /* Parity bits for the 2nd constituent encoders */ + uint8_t state1 = 0; + for (uint32_t i = 0; i < long_cb / 8; i++) { + tcod_lut_t l = tcod_lut[state1][h->temp[i]]; + uint8_t out = l.output; + parity[long_cb / 8 + i] |= (out & 0xf0) >> 4; + parity[long_cb / 8 + i + 1] = (out & 0xf) << 4; + state1 = l.next_state; + } + + /* Tail bits */ + uint8_t reg1_0, reg1_1, reg1_2, reg2_0, reg2_1, reg2_2; + uint8_t bit, in, out; + uint8_t k = 0; + uint8_t tail[12]; + + reg2_0 = (state1 & 4) >> 2; + reg2_1 = (state1 & 2) >> 1; + reg2_2 = state1 & 1; + + reg1_0 = (state0 & 4) >> 2; + reg1_1 = (state0 & 2) >> 1; + reg1_2 = state0 & 1; + + /* TAILING CODER #1 */ + for (uint32_t j = 0; j < NOF_REGS; j++) { + bit = reg1_2 ^ reg1_1; + + tail[k] = bit; + k++; + + in = bit ^ (reg1_2 ^ reg1_1); + out = reg1_2 ^ (reg1_0 ^ in); + + reg1_2 = reg1_1; + reg1_1 = reg1_0; + reg1_0 = in; + + tail[k] = out; + k++; + } + + /* TAILING CODER #2 */ + for (uint32_t j = 0; j < NOF_REGS; j++) { + bit = reg2_2 ^ reg2_1; + + tail[k] = bit; + k++; + + in = bit ^ (reg2_2 ^ reg2_1); + out = reg2_2 ^ (reg2_0 ^ in); + + reg2_2 = reg2_1; + reg2_1 = reg2_0; + reg2_0 = in; + + tail[k] = out; + k++; + } + + uint8_t tailv[3][4]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + tailv[j][i] = tail[3 * i + j]; + } + } + uint8_t* x = tailv[0]; + input[long_cb / 8] = (srslte_bit_pack(&x, 4) << 4); + x = tailv[1]; + parity[long_cb / 8] |= (srslte_bit_pack(&x, 4) << 4); + x = tailv[2]; + parity[2 * long_cb / 8] |= (srslte_bit_pack(&x, 4) & 0xf); + + return 3 * long_cb + TOTALTAIL; + } else { + return -1; + } +} + +void srslte_tcod_gentable() +{ + srslte_tc_interl_t interl; + + if (srslte_tc_interl_init(&interl, 6144)) { + ERROR("Error initiating interleave\n"); + return; + } + + for (uint32_t len = 0; len < 188; len++) { + uint32_t long_cb = srslte_cbsegm_cbsize(len); + if (srslte_tc_interl_LTE_gen(&interl, long_cb)) { + ERROR("Error initiating TC interleaver for long_cb=%d\n", long_cb); + return; + } + // Save fw/bw permutation tables + for (uint32_t i = 0; i < long_cb; i++) { + tcod_per_fw[len][i] = interl.forward[i]; + } + srslte_bit_interleaver_init(&tcod_interleavers[len], tcod_per_fw[len], long_cb); + for (uint32_t i = long_cb; i < 6144; i++) { + tcod_per_fw[len][i] = 0; + } + } + // Compute state transitions + for (uint32_t state = 0; state < 8; state++) { + for (uint32_t data = 0; data < 256; data++) { + + uint8_t reg_0, reg_1, reg_2; + reg_0 = (state & 4) >> 2; + reg_1 = (state & 2) >> 1; + reg_2 = state & 1; + + tcod_lut[state][data].output = 0; + uint8_t bit, in, out; + for (uint32_t i = 0; i < 8; i++) { + bit = (data & (1 << (7 - i))) ? 1 : 0; + + in = bit ^ (reg_2 ^ reg_1); + out = reg_2 ^ (reg_0 ^ in); + + reg_2 = reg_1; + reg_1 = reg_0; + reg_0 = in; + + tcod_lut[state][data].output |= out << (7 - i); + } + tcod_lut[state][data].next_state = (uint8_t)((reg_0 << 2 | reg_1 << 1 | reg_2) % 8); + } + } + + srslte_tc_interl_free(&interl); +} diff --git a/lib/src/phy/fec/turbo/turbodecoder.c b/lib/src/phy/fec/turbo/turbodecoder.c index 24d6f21e2..77fab09a2 100644 --- a/lib/src/phy/fec/turbo/turbodecoder.c +++ b/lib/src/phy/fec/turbo/turbodecoder.c @@ -24,14 +24,14 @@ #include #include -#include "srslte/phy/fec/turbodecoder.h" +#include "srslte/phy/fec/turbo/turbodecoder.h" #include "srslte/phy/utils/vector.h" #include "srslte/srslte.h" #define debug_enabled 0 /* Generic (no SSE) implementation */ -#include "srslte/phy/fec/turbodecoder_gen.h" +#include "srslte/phy/fec/turbo/turbodecoder_gen.h" srslte_tdec_16bit_impl_t gen_impl = {tdec_gen_init, tdec_gen_free, tdec_gen_dec, @@ -40,7 +40,7 @@ srslte_tdec_16bit_impl_t gen_impl = {tdec_gen_init, /* SSE no-window implementation */ #ifdef LV_HAVE_SSE -#include "srslte/phy/fec/turbodecoder_sse.h" +#include "srslte/phy/fec/turbo/turbodecoder_sse.h" srslte_tdec_16bit_impl_t sse_impl = {tdec_sse_init, tdec_sse_free, tdec_sse_dec, @@ -50,7 +50,7 @@ srslte_tdec_16bit_impl_t sse_impl = {tdec_sse_init, /* SSE window implementation */ #define WINIMP_IS_SSE16 -#include "srslte/phy/fec/turbodecoder_win.h" +#include "srslte/phy/fec/turbo/turbodecoder_win.h" #undef WINIMP_IS_SSE16 srslte_tdec_16bit_impl_t sse16_win_impl = {tdec_winsse16_init, @@ -63,7 +63,7 @@ srslte_tdec_16bit_impl_t sse16_win_impl = {tdec_winsse16_init, /* AVX window implementation */ #ifdef LV_HAVE_AVX2 #define WINIMP_IS_AVX16 -#include "srslte/phy/fec/turbodecoder_win.h" +#include "srslte/phy/fec/turbo/turbodecoder_win.h" #undef WINIMP_IS_AVX16 srslte_tdec_16bit_impl_t avx16_win_impl = {tdec_winavx16_init, tdec_winavx16_free, @@ -75,7 +75,7 @@ srslte_tdec_16bit_impl_t avx16_win_impl = {tdec_winavx16_init, /* SSE window implementation */ #ifdef LV_HAVE_SSE #define WINIMP_IS_SSE8 -#include "srslte/phy/fec/turbodecoder_win.h" +#include "srslte/phy/fec/turbo/turbodecoder_win.h" #undef WINIMP_IS_SSE8 srslte_tdec_8bit_impl_t sse8_win_impl = {tdec_winsse8_init, @@ -88,7 +88,7 @@ srslte_tdec_8bit_impl_t sse8_win_impl = {tdec_winsse8_init, /* AVX window implementation */ #ifdef LV_HAVE_AVX2 #define WINIMP_IS_AVX8 -#include "srslte/phy/fec/turbodecoder_win.h" +#include "srslte/phy/fec/turbo/turbodecoder_win.h" #undef WINIMP_IS_AVX8 srslte_tdec_8bit_impl_t avx8_win_impl = {tdec_winavx8_init, tdec_winavx8_free, @@ -119,11 +119,11 @@ srslte_tdec_16bit_impl_t arm16_win_impl = {tdec_winarm16_init, // Include interfaces for 8 and 16 bit decoder implementations #define LLR_IS_8BIT -#include "srslte/phy/fec/turbodecoder_iter.h" +#include "srslte/phy/fec/turbo/turbodecoder_iter.h" #undef LLR_IS_8BIT #define LLR_IS_16BIT -#include "srslte/phy/fec/turbodecoder_iter.h" +#include "srslte/phy/fec/turbo/turbodecoder_iter.h" #undef LLR_IS_16BIT int srslte_tdec_init(srslte_tdec_t* h, uint32_t max_long_cb) diff --git a/lib/src/phy/fec/turbo/turbodecoder_gen.c b/lib/src/phy/fec/turbo/turbodecoder_gen.c index 1f63274a1..d8db25f75 100644 --- a/lib/src/phy/fec/turbo/turbodecoder_gen.c +++ b/lib/src/phy/fec/turbo/turbodecoder_gen.c @@ -26,7 +26,7 @@ #include #include -#include "srslte/phy/fec/turbodecoder_gen.h" +#include "srslte/phy/fec/turbo/turbodecoder_gen.h" #include "srslte/phy/utils/vector.h" #define NUMSTATES 8 diff --git a/lib/src/phy/fec/turbo/turbodecoder_sse.c b/lib/src/phy/fec/turbo/turbodecoder_sse.c index 9c057b57c..e947aead0 100644 --- a/lib/src/phy/fec/turbo/turbodecoder_sse.c +++ b/lib/src/phy/fec/turbo/turbodecoder_sse.c @@ -26,7 +26,7 @@ #include #include -#include "srslte/phy/fec/turbodecoder_sse.h" +#include "srslte/phy/fec/turbo/turbodecoder_sse.h" #include "srslte/phy/utils/vector.h" #include diff --git a/lib/src/phy/phch/npdsch.c b/lib/src/phy/phch/npdsch.c index b2d5e425f..4257571f2 100644 --- a/lib/src/phy/phch/npdsch.c +++ b/lib/src/phy/phch/npdsch.c @@ -29,7 +29,7 @@ #include "prb_dl.h" #include "srslte/phy/common/phy_common.h" -#include "srslte/phy/fec/rm_conv.h" +#include "srslte/phy/fec/convolutional/rm_conv.h" #include "srslte/phy/phch/npdsch.h" #include "srslte/phy/utils/bit.h" #include "srslte/phy/utils/debug.h" diff --git a/lib/src/phy/phch/psbch.c b/lib/src/phy/phch/psbch.c index 52ed500ab..46ae941c5 100644 --- a/lib/src/phy/phch/psbch.c +++ b/lib/src/phy/phch/psbch.c @@ -20,7 +20,7 @@ */ #include "srslte/phy/phch/psbch.h" -#include "srslte/phy/fec/rm_conv.h" +#include "srslte/phy/fec/convolutional/rm_conv.h" #include "srslte/phy/modem/mod.h" #include "srslte/phy/phch/sch.h" #include "srslte/phy/utils/bit.h" diff --git a/lib/src/phy/phch/pscch.c b/lib/src/phy/phch/pscch.c index 47be55a80..91827ad8d 100644 --- a/lib/src/phy/phch/pscch.c +++ b/lib/src/phy/phch/pscch.c @@ -23,7 +23,7 @@ #include #include -#include "srslte/phy/fec/rm_conv.h" +#include "srslte/phy/fec/convolutional/rm_conv.h" #include "srslte/phy/modem/demod_soft.h" #include "srslte/phy/modem/mod.h" #include "srslte/phy/phch/pscch.h" diff --git a/lib/src/phy/phch/pssch.c b/lib/src/phy/phch/pssch.c index 73886d6ee..9cb057a2f 100644 --- a/lib/src/phy/phch/pssch.c +++ b/lib/src/phy/phch/pssch.c @@ -21,7 +21,7 @@ #include -#include "srslte/phy/fec/rm_turbo.h" +#include "srslte/phy/fec/turbo/rm_turbo.h" #include "srslte/phy/modem/demod_soft.h" #include "srslte/phy/phch/pssch.h" #include "srslte/phy/phch/ra.h" diff --git a/lib/src/phy/phch/uci.c b/lib/src/phy/phch/uci.c index 1550f0d6e..8ad19cd33 100644 --- a/lib/src/phy/phch/uci.c +++ b/lib/src/phy/phch/uci.c @@ -29,10 +29,10 @@ #include #include "srslte/phy/common/phy_common.h" -#include "srslte/phy/fec/cbsegm.h" -#include "srslte/phy/fec/convcoder.h" +#include "srslte/phy/fec/convolutional/convcoder.h" +#include "srslte/phy/fec/convolutional/rm_conv.h" #include "srslte/phy/fec/crc.h" -#include "srslte/phy/fec/rm_conv.h" +#include "srslte/phy/fec/turbo/cbsegm.h" #include "srslte/phy/phch/uci.h" #include "srslte/phy/utils/bit.h" #include "srslte/phy/utils/debug.h"