diff --git a/lib/include/srslte/phy/phch/sch.h b/lib/include/srslte/phy/phch/sch.h index 4ef0328e7..003e9b7df 100644 --- a/lib/include/srslte/phy/phch/sch.h +++ b/lib/include/srslte/phy/phch/sch.h @@ -64,7 +64,7 @@ typedef struct SRSLTE_API { uint8_t *parity_bits; void *e; uint8_t *temp_g_bits; - uint16_t *ul_interleaver; + uint32_t *ul_interleaver; srslte_uci_bit_t ack_ri_bits[12*288]; uint32_t nof_ri_ack_bits; diff --git a/lib/include/srslte/phy/utils/bit.h b/lib/include/srslte/phy/utils/bit.h index 29fca8e9e..8a4ff789b 100644 --- a/lib/include/srslte/phy/utils/bit.h +++ b/lib/include/srslte/phy/utils/bit.h @@ -70,6 +70,17 @@ SRSLTE_API void srslte_bit_copy(uint8_t *dst, uint32_t src_offset, uint32_t nof_bits); +SRSLTE_API void srslte_bit_interleave_i(uint8_t *input, + uint8_t *output, + uint32_t *interleaver, + uint32_t nof_bits); + +SRSLTE_API void srslte_bit_interleave_i_w_offset(uint8_t *input, + uint8_t *output, + uint32_t *interleaver, + uint32_t nof_bits, + uint32_t w_offset); + SRSLTE_API void srslte_bit_interleave_w_offset(uint8_t *input, uint8_t *output, uint16_t *interleaver, diff --git a/lib/include/srslte/phy/utils/vector.h b/lib/include/srslte/phy/utils/vector.h index 1fcbe4235..d6742fb3c 100644 --- a/lib/include/srslte/phy/utils/vector.h +++ b/lib/include/srslte/phy/utils/vector.h @@ -99,6 +99,7 @@ SRSLTE_API void srslte_vec_convert_fi(const float *x, const float scale, int16_t SRSLTE_API void srslte_vec_convert_if(const int16_t *x, const float scale, float *z, const uint32_t len); SRSLTE_API void srslte_vec_lut_sss(const short *x, const unsigned short *lut, short *y, const uint32_t len); +SRSLTE_API void srslte_vec_lut_sis(const short *x, const unsigned int *lut, short *y, const uint32_t len); /* vector product (element-wise) */ SRSLTE_API void srslte_vec_prod_ccc(const cf_t *x, const cf_t *y, cf_t *z, const uint32_t len); diff --git a/lib/src/phy/phch/sch.c b/lib/src/phy/phch/sch.c index b679e00f9..f419ea826 100644 --- a/lib/src/phy/phch/sch.c +++ b/lib/src/phy/phch/sch.c @@ -130,7 +130,7 @@ int srslte_sch_init(srslte_sch_t *q) { goto clean; } bzero(q->temp_g_bits, SRSLTE_MAX_PRB*12*12*12); - q->ul_interleaver = srslte_vec_malloc(sizeof(uint16_t)*SRSLTE_MAX_PRB*12*12*12); + q->ul_interleaver = srslte_vec_malloc(sizeof(uint32_t)*SRSLTE_MAX_PRB*12*12*12); if (!q->ul_interleaver) { goto clean; } @@ -577,7 +577,7 @@ int srslte_dlsch_encode2(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbu * Profiling show that the computation of this matrix is neglegible. */ static void ulsch_interleave_gen(uint32_t H_prime_total, uint32_t N_pusch_symbs, uint32_t Qm, - uint8_t *ri_present, uint16_t *interleaver_lut) + uint8_t *ri_present, uint32_t *interleaver_lut) { uint32_t rows = H_prime_total/N_pusch_symbs; uint32_t cols = N_pusch_symbs; @@ -599,7 +599,7 @@ static void ulsch_interleave_gen(uint32_t H_prime_total, uint32_t N_pusch_symbs, /* UL-SCH channel interleaver according to 5.2.2.8 of 36.212 */ void ulsch_interleave(uint8_t *g_bits, uint32_t Qm, uint32_t H_prime_total, uint32_t N_pusch_symbs, uint8_t *q_bits, srslte_uci_bit_t *ri_bits, uint32_t nof_ri_bits, - uint8_t *ri_present, uint16_t *inteleaver_lut) + uint8_t *ri_present, uint32_t *inteleaver_lut) { // Prepare ri_bits for fast search using temp_buffer @@ -611,7 +611,7 @@ void ulsch_interleave(uint8_t *g_bits, uint32_t Qm, uint32_t H_prime_total, // Genearate interleaver table and interleave bits ulsch_interleave_gen(H_prime_total, N_pusch_symbs, Qm, ri_present, inteleaver_lut); - srslte_bit_interleave(g_bits, q_bits, inteleaver_lut, H_prime_total*Qm); + srslte_bit_interleave_i(g_bits, q_bits, inteleaver_lut, H_prime_total*Qm); // Reset temp_buffer because will be reused next time if (nof_ri_bits > 0) { @@ -624,7 +624,7 @@ void ulsch_interleave(uint8_t *g_bits, uint32_t Qm, uint32_t H_prime_total, /* UL-SCH channel deinterleaver according to 5.2.2.8 of 36.212 */ void ulsch_deinterleave(int16_t *q_bits, uint32_t Qm, uint32_t H_prime_total, uint32_t N_pusch_symbs, int16_t *g_bits, srslte_uci_bit_t *ri_bits, uint32_t nof_ri_bits, - uint8_t *ri_present, uint16_t *inteleaver_lut) + uint8_t *ri_present, uint32_t *inteleaver_lut) { // Prepare ri_bits for fast search using temp_buffer if (nof_ri_bits > 0) { @@ -634,8 +634,8 @@ void ulsch_deinterleave(int16_t *q_bits, uint32_t Qm, uint32_t H_prime_total, } // Generate interleaver table and interleave samples - ulsch_interleave_gen(H_prime_total, N_pusch_symbs, Qm, ri_present, inteleaver_lut); - srslte_vec_lut_sss(q_bits, inteleaver_lut, g_bits, H_prime_total*Qm); + ulsch_interleave_gen(H_prime_total, N_pusch_symbs, Qm, ri_present, inteleaver_lut); + srslte_vec_lut_sis(q_bits, inteleaver_lut, g_bits, H_prime_total*Qm); // Reset temp_buffer because will be reused next time if (nof_ri_bits > 0) { diff --git a/lib/src/phy/utils/bit.c b/lib/src/phy/utils/bit.c index f4e97fad6..6ef061252 100644 --- a/lib/src/phy/utils/bit.c +++ b/lib/src/phy/utils/bit.c @@ -205,6 +205,65 @@ void srslte_bit_interleaver_run(srslte_bit_interleaver_t *q, uint8_t *input, uin } +void srslte_bit_interleave_i(uint8_t *input, uint8_t *output, uint32_t *interleaver, uint32_t nof_bits) { + srslte_bit_interleave_i_w_offset(input, output, interleaver, nof_bits, 0); +} + +void srslte_bit_interleave_i_w_offset(uint8_t *input, uint8_t *output, uint32_t *interleaver, uint32_t nof_bits, uint32_t w_offset) { + uint32_t st=0, w_offset_p=0; + static const uint8_t mask[] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 }; + + if (w_offset < 8 && w_offset > 0) { + st=1; + for (uint32_t j=0;j<8-w_offset;j++) { + uint32_t i_p = interleaver[j]; + if (input[i_p/8] & mask[i_p%8]) { + output[0] |= mask[j+w_offset]; + } else { + output[0] &= ~(mask[j+w_offset]); + } + } + w_offset_p=8-w_offset; + } + for (uint32_t i=st;i