Fixed UL interleaver (missing SIMD deinterleaver)

This commit is contained in:
Ismael Gomez 2018-04-17 19:16:04 +02:00
parent 190015435b
commit 384e0f8649
6 changed files with 85 additions and 8 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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) {

View File

@ -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<nof_bits/8;i++) {
uint32_t i_p0 = interleaver[i*8+0-w_offset_p];
uint32_t i_p1 = interleaver[i*8+1-w_offset_p];
uint32_t i_p2 = interleaver[i*8+2-w_offset_p];
uint32_t i_p3 = interleaver[i*8+3-w_offset_p];
uint32_t i_p4 = interleaver[i*8+4-w_offset_p];
uint32_t i_p5 = interleaver[i*8+5-w_offset_p];
uint32_t i_p6 = interleaver[i*8+6-w_offset_p];
uint32_t i_p7 = interleaver[i*8+7-w_offset_p];
uint8_t out0 = (input[i_p0/8] & mask[i_p0%8])?mask[0]:0;
uint8_t out1 = (input[i_p1/8] & mask[i_p1%8])?mask[1]:0;
uint8_t out2 = (input[i_p2/8] & mask[i_p2%8])?mask[2]:0;
uint8_t out3 = (input[i_p3/8] & mask[i_p3%8])?mask[3]:0;
uint8_t out4 = (input[i_p4/8] & mask[i_p4%8])?mask[4]:0;
uint8_t out5 = (input[i_p5/8] & mask[i_p5%8])?mask[5]:0;
uint8_t out6 = (input[i_p6/8] & mask[i_p6%8])?mask[6]:0;
uint8_t out7 = (input[i_p7/8] & mask[i_p7%8])?mask[7]:0;
output[i] = out0 | out1 | out2 | out3 | out4 | out5 | out6 | out7;
}
for (uint32_t j=0;j<nof_bits%8;j++) {
uint32_t i_p = interleaver[(nof_bits/8)*8+j-w_offset];
if (input[i_p/8] & mask[i_p%8]) {
output[nof_bits/8] |= mask[j];
} else {
output[nof_bits/8] &= ~(mask[j]);
}
}
for (uint32_t j=0;j<w_offset;j++) {
uint32_t i_p = interleaver[(nof_bits/8)*8+j-w_offset];
if (input[i_p/8] & (1<<(7-i_p%8))) {
output[nof_bits/8] |= mask[j];
} else {
output[nof_bits/8] &= ~(mask[j]);
}
}
}
void srslte_bit_interleave(uint8_t *input, uint8_t *output, uint16_t *interleaver, uint32_t nof_bits) {
srslte_bit_interleave_w_offset(input, output, interleaver, nof_bits, 0);

View File

@ -104,6 +104,12 @@ void srslte_vec_lut_sss(const short *x, const unsigned short *lut, short *y, con
srslte_vec_lut_sss_simd(x, lut, y, len);
}
void srslte_vec_lut_sis(const short *x, const unsigned int *lut, short *y, const uint32_t len) {
for (int i=0; i < len; i++) {
y[lut[i]] = x[i];
}
}
void *srslte_vec_malloc(uint32_t size) {
void *ptr;
if (posix_memalign(&ptr, SRSLTE_SIMD_BIT_ALIGN, size)) {