diff --git a/lib/include/srslte/phy/fec/ldpc/ldpc_rm.h b/lib/include/srslte/phy/fec/ldpc/ldpc_rm.h index 2c087f3b6..2ccf51cc6 100644 --- a/lib/include/srslte/phy/fec/ldpc/ldpc_rm.h +++ b/lib/include/srslte/phy/fec/ldpc/ldpc_rm.h @@ -97,7 +97,8 @@ SRSLTE_API int srslte_ldpc_rm_rx_init_f(srslte_ldpc_rm_t* q); * \param[in] input The LLRs obtained from the channel samples that correspond to * the codeword to be first, rate-dematched and then decoded. * \param[out] output The rate-dematched codeword resulting from the rate-dematching - * operation. + * operation. Shall be either initialized to all zeros or to the + * result of previous redundancy versions is available. * \param[in] E Rate-matched codeword length. * \param[in] F Number of filler bits. * \param[in] bg; Current base graph. @@ -131,6 +132,9 @@ SRSLTE_API int srslte_ldpc_rm_rx_init_s(srslte_ldpc_rm_t* q); * instance) that carries out the rate matching. * \param[in] input The LLRs obtained from the channel samples that correspond to * the codeword to be first, rate-dematched and then decoded. + * \param[out] output The rate-dematched codeword resulting from the rate-dematching + * operation. Shall be either initialized to all zeros or to the + * result of previous redundancy versions is available. * \param[in] E Rate-matched codeword length. * \param[in] F Number of filler bits. * \param[in] bg; Current base graph. @@ -165,8 +169,9 @@ SRSLTE_API int srslte_ldpc_rm_rx_init_c(srslte_ldpc_rm_t* q); * instance) that carries out the rate matching. * \param[in] input The LLRs obtained from the channel samples that correspond to * the codeword to be first, rate-dematched and then decoded. - * \param[out] output The rate-dematched codeword resulting from the rate-dematching - * operation. + * \param[out] output The rate-dematched codeword resulting from the rate-dematching + * operation. Shall be either initialized to all zeros or to the + * result of previous redundancy versions is available. * \param[in] E Rate-matched codeword length. * \param[in] F Number of filler bits. * \param[in] bg; Current base graph. diff --git a/lib/src/phy/fec/ldpc/ldpc_rm.c b/lib/src/phy/fec/ldpc/ldpc_rm.c index f2faf3daf..b5e34be6d 100644 --- a/lib/src/phy/fec/ldpc/ldpc_rm.c +++ b/lib/src/phy/fec/ldpc/ldpc_rm.c @@ -191,11 +191,12 @@ static void bit_selection_rm_tx(const uint8_t* input, * The output has the codeword length N. It inserts filler bits as INFINITY symbols * (to indicate very reliable 0 bit), and set to 0 (completely unknown bit) all * missing symbol. Repeated symbols are added. + * The input memory *output shall be either initialized to all zeros or to the + * result of previous redundancy versions is available. */ static void bit_selection_rm_rx(const float* input, const uint32_t in_len, float* output, - const uint32_t out_len, uint32_t* indices, const uint32_t ini_exclude, const uint32_t end_exclude, @@ -203,7 +204,6 @@ static void bit_selection_rm_rx(const float* input, const uint32_t Ncb) { uint32_t E = in_len; - uint32_t N = out_len; uint32_t k = 0; uint32_t j = 0; @@ -217,9 +217,6 @@ static void bit_selection_rm_rx(const float* input, j = j + 1; } // while - // Initializes the data_decoded_vector to all zeros - bzero(output, N * sizeof(float)); - // set filler bits to INFINITY for (uint32_t i = ini_exclude; i < end_exclude; i++) { output[i] = INFINITY; @@ -236,11 +233,12 @@ static void bit_selection_rm_rx(const float* input, * The output has the codeword length N. It inserts filler bits as INFINITY symbols * (to indicate very reliable 0 bit), and set to 0 (completely unknown bit) all * missing symbol. Repeated symbols are added. + * The input memory *output shall be either initialized to all zeros or to the + * result of previous redundancy versions is available. */ static void bit_selection_rm_rx_s(const int16_t* input, const uint32_t in_len, int16_t* output, - const uint32_t out_len, uint32_t* indices, const uint32_t ini_exclude, const uint32_t end_exclude, @@ -248,7 +246,6 @@ static void bit_selection_rm_rx_s(const int16_t* input, const uint32_t Ncb) { uint32_t E = in_len; - uint32_t N = out_len; uint32_t k = 0; uint32_t j = 0; @@ -262,9 +259,6 @@ static void bit_selection_rm_rx_s(const int16_t* input, j = j + 1; } // while - // Initializes the data_decoded_vector to all zeros - bzero(output, N * sizeof(int16_t)); - // set filler bits to INFINITY const long infinity16 = (1U << 15U) - 1; // Max positive value in 16-bit representation for (uint32_t i = ini_exclude; i < end_exclude; i++) { @@ -293,11 +287,12 @@ static void bit_selection_rm_rx_s(const int16_t* input, * The output has the codeword length N. It inserts filler bits as INFINITY symbols * (to indicate very reliable 0 bit), and set to 0 (completely unknown bit) all * missing symbol. Repeated symbols are added. + * The input memory *output shall be either initialized to all zeros or to the + * result of previous redundancy versions is available. */ static void bit_selection_rm_rx_c(const int8_t* input, const uint32_t in_len, int8_t* output, - const uint32_t out_len, uint32_t* indices, const uint32_t ini_exclude, const uint32_t end_exclude, @@ -305,7 +300,6 @@ static void bit_selection_rm_rx_c(const int8_t* input, const uint32_t Ncb) { uint32_t E = in_len; - uint32_t N = out_len; uint32_t k = 0; uint32_t j = 0; @@ -319,9 +313,6 @@ static void bit_selection_rm_rx_c(const int8_t* input, j = j + 1; } // while - // Initializes the data_decoded_vector to all zeros - bzero(output, N * sizeof(int8_t)); - // set filler bits to INFINITY const long infinity8 = (1U << 7U) - 1; // Max positive value in 8-bit representation for (uint32_t i = ini_exclude; i < end_exclude; i++) { @@ -637,10 +628,10 @@ int srslte_ldpc_rm_rx_f(srslte_ldpc_rm_t* q, uint32_t ini_exclude = end_exclude - q->F; if (q->mod_order == 1) { // interleaver can be skipped - bit_selection_rm_rx(input, q->E, output, q->N, indices, ini_exclude, end_exclude, q->k0, q->Ncb); + bit_selection_rm_rx(input, q->E, output, indices, ini_exclude, end_exclude, q->k0, q->Ncb); } else { bit_interleaver_rm_rx(input, tmp_rm_symbol, q->E, q->mod_order); - bit_selection_rm_rx(tmp_rm_symbol, q->E, output, q->N, indices, ini_exclude, end_exclude, q->k0, q->Ncb); + bit_selection_rm_rx(tmp_rm_symbol, q->E, output, indices, ini_exclude, end_exclude, q->k0, q->Ncb); } return 0; } @@ -669,10 +660,10 @@ int srslte_ldpc_rm_rx_s(srslte_ldpc_rm_t* q, uint32_t ini_exclude = end_exclude - q->F; if (q->mod_order == 1) { // interleaver can be skipped - bit_selection_rm_rx_s(input, q->E, output, q->N, indices, ini_exclude, end_exclude, q->k0, q->Ncb); + bit_selection_rm_rx_s(input, q->E, output, indices, ini_exclude, end_exclude, q->k0, q->Ncb); } else { bit_interleaver_rm_rx_s(input, tmp_rm_symbol, q->E, q->mod_order); - bit_selection_rm_rx_s(tmp_rm_symbol, q->E, output, q->N, indices, ini_exclude, end_exclude, q->k0, q->Ncb); + bit_selection_rm_rx_s(tmp_rm_symbol, q->E, output, indices, ini_exclude, end_exclude, q->k0, q->Ncb); } return 0; @@ -702,10 +693,10 @@ int srslte_ldpc_rm_rx_c(srslte_ldpc_rm_t* q, uint32_t ini_exclude = end_exclude - q->F; if (q->mod_order == 1) { // interleaver can be skipped - bit_selection_rm_rx_c(input, q->E, output, q->N, indices, ini_exclude, end_exclude, q->k0, q->Ncb); + bit_selection_rm_rx_c(input, q->E, output, indices, ini_exclude, end_exclude, q->k0, q->Ncb); } else { bit_interleaver_rm_rx_c(input, tmp_rm_symbol, q->E, q->mod_order); - bit_selection_rm_rx_c(tmp_rm_symbol, q->E, output, q->N, indices, ini_exclude, end_exclude, q->k0, q->Ncb); + bit_selection_rm_rx_c(tmp_rm_symbol, q->E, output, indices, ini_exclude, end_exclude, q->k0, q->Ncb); } return 0; diff --git a/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c b/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c index 7179e226d..219f9ca2b 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c @@ -407,6 +407,14 @@ int main(int argc, char** argv) } } + // HARQ procedure. Use previous previous rate-matched outputs if available from the previous redundancy versions, + // otherwise initialize to zeros. + for (i = 0; i < batch_size; i++) { + bzero(symbols + i * finalN, finalN * sizeof(float)); + bzero(symbols_s + i * finalN, finalN * sizeof(int16_t)); + bzero(symbols_c + i * finalN, finalN * sizeof(int8_t)); + } + for (i = 0; i < batch_size; i++) { if (srslte_ldpc_rm_rx_f(&rm_rx, rm_symbols + i * rm_length, diff --git a/lib/src/phy/fec/ldpc/test/ldpc_rm_test.c b/lib/src/phy/fec/ldpc/test/ldpc_rm_test.c index 6b0d053c2..319d5c194 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_rm_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_rm_test.c @@ -250,6 +250,12 @@ int main(int argc, char** argv) rm_symbols_c[r * E + i] = rm_codewords[r * E + i] ? -1 : 1; } + // HARQ procedure. Use previous previous rate-matched outputs if available from the previous redundancy versions, + // otherwise initialize to zeros. + bzero(unrm_symbols + r * N, N * sizeof(float)); + bzero(unrm_symbols_s + r * N, N * sizeof(int16_t)); + bzero(unrm_symbols_c + r * N, N * sizeof(int8_t)); + if (srslte_ldpc_rm_rx_f( &rm_rx, rm_symbols + r * E, unrm_symbols + r * N, E, F, base_graph, lift_size, rv, mod_type, Nref)) { exit(-1);