mirror of https://github.com/PentHertz/srsLTE.git
Fixed UL interleaver (missing SIMD deinterleaver)
This commit is contained in:
parent
190015435b
commit
384e0f8649
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Loading…
Reference in New Issue