mirror of https://github.com/pvnis/srsRAN_4G.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
4.4 KiB
C
146 lines
4.4 KiB
C
4 years ago
|
/**
|
||
6 years ago
|
*
|
||
4 years ago
|
* \section COPYRIGHT
|
||
6 years ago
|
*
|
||
4 years ago
|
* Copyright 2013-2021 Software Radio Systems Limited
|
||
6 years ago
|
*
|
||
4 years ago
|
* By using this file, you agree to the terms and conditions set
|
||
|
* forth in the LICENSE file which can be found at the top level of
|
||
|
* the distribution.
|
||
6 years ago
|
*
|
||
|
*/
|
||
|
|
||
4 years ago
|
#include "srsran/config.h"
|
||
6 years ago
|
|
||
5 years ago
|
#define MAKE_CALL(a) CONCAT2(a, type_name)
|
||
|
#define MAKE_VEC(a) CONCAT2(a, vec_suffix)
|
||
4 years ago
|
#define PRINT CONCAT2(srsran_vec_fprint, print_suffix)
|
||
6 years ago
|
|
||
|
#ifdef LLR_IS_8BIT
|
||
|
#define llr_t int8_t
|
||
|
#define type_name _8bit
|
||
|
#define vec_suffix _bbb
|
||
|
#define print_suffix _bs
|
||
|
#define decptr h->dec8[h->current_dec]
|
||
|
#define dechdlr h->dec8_hdlr[h->current_dec]
|
||
|
#define input_is_interleaved 1
|
||
|
#else
|
||
|
#ifdef LLR_IS_16BIT
|
||
5 years ago
|
#define llr_t int16_t
|
||
|
#define vec_suffix _sss
|
||
|
#define print_suffix _s
|
||
|
#define decptr h->dec16[h->current_dec]
|
||
|
#define dechdlr h->dec16_hdlr[h->current_dec]
|
||
|
#define input_is_interleaved (h->current_dec > 0)
|
||
6 years ago
|
#define type_name _16bit
|
||
5 years ago
|
#else
|
||
6 years ago
|
#pragma message "Unsupported LLR mode"
|
||
|
#endif
|
||
6 years ago
|
#endif
|
||
|
|
||
|
#define debug_enabled_iter 0
|
||
5 years ago
|
#define debug_len 20
|
||
6 years ago
|
|
||
5 years ago
|
#define debug_vec(a) \
|
||
|
if (debug_enabled_iter) { \
|
||
|
printf("%s it=%d: ", STRING(a), n_iter); \
|
||
|
PRINT(stdout, a, debug_len); \
|
||
|
}
|
||
6 years ago
|
|
||
5 years ago
|
static void MAKE_CALL(
|
||
|
extract_input_tail_sb)(llr_t* input, llr_t* syst, llr_t* app2, llr_t* parity0, llr_t* parity1, uint32_t long_cb)
|
||
6 years ago
|
{
|
||
|
for (int i = long_cb; i < long_cb + 3; i++) {
|
||
5 years ago
|
syst[i] = input[3 * (long_cb + 32) + 2 * (i - long_cb)];
|
||
|
parity0[i] = input[3 * (long_cb + 32) + 2 * (i - long_cb) + 1];
|
||
6 years ago
|
|
||
5 years ago
|
app2[i] = input[3 * (long_cb + 32) + 6 + 2 * (i - long_cb)];
|
||
|
parity1[i] = input[3 * (long_cb + 32) + 6 + 2 * (i - long_cb) + 1];
|
||
6 years ago
|
}
|
||
|
}
|
||
|
|
||
|
/* Runs 1 turbo decoder iteration */
|
||
4 years ago
|
void MAKE_CALL(run_tdec_iteration)(srsran_tdec_t* h, llr_t* input)
|
||
6 years ago
|
{
|
||
|
|
||
|
if (h->current_cbidx >= 0) {
|
||
5 years ago
|
uint16_t* inter = h->interleaver[h->current_inter_idx][h->current_cbidx].forward;
|
||
|
uint16_t* deinter = h->interleaver[h->current_inter_idx][h->current_cbidx].reverse;
|
||
|
llr_t* syst = (llr_t*)h->syst0;
|
||
|
llr_t* parity0 = (llr_t*)h->parity0;
|
||
|
llr_t* parity1 = (llr_t*)h->parity1;
|
||
6 years ago
|
|
||
5 years ago
|
llr_t* app1 = (llr_t*)h->app1;
|
||
|
llr_t* app2 = (llr_t*)h->app2;
|
||
|
llr_t* ext1 = (llr_t*)h->ext1;
|
||
|
llr_t* ext2 = (llr_t*)h->ext2;
|
||
6 years ago
|
|
||
|
uint32_t long_cb = h->current_long_cb;
|
||
|
uint32_t n_iter = h->n_iter;
|
||
5 years ago
|
|
||
4 years ago
|
if (SRSRAN_TDEC_EXPECT_INPUT_SB && !h->force_not_sb && input_is_interleaved) {
|
||
6 years ago
|
syst = input;
|
||
|
// align to 32 bytes (warning: must be same alignment as in rm_turbo.c)
|
||
5 years ago
|
parity0 = &input[long_cb + 32];
|
||
|
parity1 = &input[2 * (long_cb + 32)];
|
||
6 years ago
|
if (n_iter == 0) {
|
||
|
MAKE_CALL(extract_input_tail_sb)(input, syst, app2, parity0, parity1, long_cb);
|
||
|
}
|
||
|
} else {
|
||
|
if (n_iter == 0) {
|
||
|
decptr->tdec_extract_input(input, syst, app2, parity0, parity1, long_cb);
|
||
|
}
|
||
|
}
|
||
5 years ago
|
|
||
|
if ((n_iter % 2) == 0) {
|
||
6 years ago
|
|
||
|
// Add apriori information to decoder 1
|
||
|
if (n_iter) {
|
||
4 years ago
|
MAKE_VEC(srsran_vec_sub)(app1, ext1, app1, long_cb);
|
||
6 years ago
|
}
|
||
|
|
||
|
// Run MAP DEC #1
|
||
|
decptr->tdec_dec(dechdlr, syst, n_iter ? app1 : NULL, parity0, ext1, long_cb);
|
||
|
}
|
||
|
// Interleave extrinsic output of DEC1 to form apriori info for decoder 2
|
||
5 years ago
|
if (n_iter % 2) {
|
||
6 years ago
|
// Convert aposteriori information into extrinsic information
|
||
|
if (n_iter > 1) {
|
||
4 years ago
|
MAKE_VEC(srsran_vec_sub)(ext1, app1, ext1, long_cb);
|
||
6 years ago
|
}
|
||
|
|
||
4 years ago
|
MAKE_VEC(srsran_vec_lut)(ext1, deinter, app2, long_cb);
|
||
6 years ago
|
|
||
|
// Run MAP DEC #2. 2nd decoder uses apriori information as systematic bits
|
||
|
decptr->tdec_dec(dechdlr, app2, NULL, parity1, ext2, long_cb);
|
||
|
|
||
|
// Deinterleaved extrinsic bits become apriori info for decoder 1
|
||
4 years ago
|
MAKE_VEC(srsran_vec_lut)(ext2, inter, app1, long_cb);
|
||
6 years ago
|
}
|
||
|
|
||
|
if (h->n_iter == 0) {
|
||
|
debug_vec(syst);
|
||
|
debug_vec(parity0);
|
||
|
debug_vec(parity1);
|
||
|
}
|
||
|
debug_vec(ext1);
|
||
|
debug_vec(ext2);
|
||
|
debug_vec(app1);
|
||
|
debug_vec(app2);
|
||
|
|
||
|
h->n_iter++;
|
||
|
} else {
|
||
4 years ago
|
ERROR("Error CB index not set (call srsran_tdec_new_cb() first");
|
||
6 years ago
|
}
|
||
|
}
|
||
|
|
||
|
#undef debug_enabled
|
||
|
#undef debug_len
|
||
|
#undef debug_vec
|
||
|
#undef llr_t
|
||
|
#undef vec_suffix
|
||
|
#undef print_suffix
|
||
|
#undef decptr
|
||
|
#undef dechdlr
|
||
|
#undef type_name
|
||
|
#undef input_is_interleaved
|