PUSCH interleaver working

master
Ismael Gomez 9 years ago
parent 8de159dc29
commit e30f3f7f4e

@ -120,7 +120,8 @@ SRSLTE_API int srslte_ulsch_uci_encode(srslte_sch_t *q,
SRSLTE_API int srslte_ulsch_decode(srslte_sch_t *q,
srslte_pusch_cfg_t *cfg,
srslte_softbuffer_rx_t *softbuffer,
int16_t *e_bits,
int16_t *q_bits,
int16_t *g_bits,
uint8_t *data);
SRSLTE_API float srslte_sch_beta_cqi(uint32_t I_cqi);

@ -557,16 +557,16 @@ int srslte_pusch_decode(srslte_pusch_t *q,
srslte_vec_save_file("rx_symbols", q->d, sizeof(cf_t)*cfg->nbits.nof_re);
// Soft demodulation
srslte_demod_soft_demodulate(cfg->grant.mcs.mod, q->d, q->q, cfg->nbits.nof_re);
srslte_demod_soft_demodulate_s(cfg->grant.mcs.mod, q->d, q->q, cfg->nbits.nof_re);
srslte_vec_save_file("rx_bits_scram", q->q, sizeof(float)*cfg->nbits.nof_bits);
srslte_vec_save_file("rx_bits_scram", q->q, sizeof(int16_t)*cfg->nbits.nof_bits);
// Descrambling
srslte_scrambling_f_offset(&q->seq[cfg->sf_idx], q->q, 0, cfg->nbits.nof_bits);
srslte_scrambling_s_offset(&q->seq[cfg->sf_idx], q->q, 0, cfg->nbits.nof_bits);
srslte_vec_save_file("rx_bits", q->q, sizeof(float)*cfg->nbits.nof_bits);
srslte_vec_save_file("rx_bits", q->q, sizeof(int16_t)*cfg->nbits.nof_bits);
return srslte_ulsch_decode(&q->dl_sch, cfg, softbuffer, q->q, data);
return srslte_ulsch_decode(&q->dl_sch, cfg, softbuffer, q->q, q->g, data);
} else {
fprintf(stderr, "Must call srslte_pusch_set_rnti() before calling srslte_pusch_decode()\n");
return SRSLTE_ERROR;

@ -498,114 +498,90 @@ int srslte_dlsch_encode(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuf
data, e_bits);
}
/* 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,
uint16_t *interleaver_buffer, uint8_t *temp_buffer, uint32_t buffer_sz)
/* Compute the interleaving function on-the-fly, because it depends on number of RI bits
* 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)
{
uint32_t rows = H_prime_total/N_pusch_symbs;
uint32_t cols = N_pusch_symbs;
// Prepare ri_bits for fast search using temp_buffer
if (nof_ri_bits > 0) {
for (uint32_t i=0;i<nof_ri_bits;i++) {
if (ri_bits[i].position < buffer_sz) {
temp_buffer[ri_bits[i].position] = 1;
} else {
fprintf(stderr, "Error computing ULSCH interleaver RI bits. Position %d exceeds buffer size %d\n", ri_bits[i].position, buffer_sz);
}
}
}
/* Compute the interleaving function on-the-fly, because it depends on number of RI bits
* Profiling show that the computation of this matrix is neglegible.
*/
uint32_t idx = 0;
for(uint32_t j=0; j<rows; j++) {
for(uint32_t i=0; i<cols; i++) {
for(uint32_t k=0; k<Qm; k++) {
if (temp_buffer[j*Qm + i*rows*Qm + k]) {
interleaver_buffer[j*Qm + i*rows*Qm + k] = 0;
if (ri_present[j*Qm + i*rows*Qm + k]) {
interleaver_lut[j*Qm + i*rows*Qm + k] = 0;
} else {
if (j*Qm + i*rows*Qm + k < buffer_sz) {
interleaver_buffer[j*Qm + i*rows*Qm + k] = idx;
idx++;
} else {
fprintf(stderr, "Error computing ULSCH interleaver. Position %d exceeds buffer size %d\n", j*Qm + i*rows*Qm + k, buffer_sz);
}
interleaver_lut[j*Qm + i*rows*Qm + k] = idx;
idx++;
}
}
}
}
srslte_bit_interleave(g_bits, q_bits, interleaver_buffer, H_prime_total*Qm);
// Reset temp_buffer because will be reused next time
printf("rows=%d, cols=%d, Qm=%d, total=%d, symb=%d\n", rows, cols, Qm, H_prime_total, 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)
{
// Prepare ri_bits for fast search using temp_buffer
if (nof_ri_bits > 0) {
for (uint32_t i=0;i<nof_ri_bits;i++) {
if (ri_bits[i].position < buffer_sz) {
temp_buffer[ri_bits[i].position] = 0;
} else {
fprintf(stderr, "Error computing ULSCH interleaver RI bits. Position %d exceeds buffer size %d\n", ri_bits[i].position, buffer_sz);
}
ri_present[ri_bits[i].position] = 1;
}
}
}
uint16_t deinterleaver_buffer[100000];
// 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);
/* UL-SCH channel deinterleaver according to 5.2.2.8 of 36.212 */
void ulsch_deinterleave(uint8_t *q_bits, uint32_t Qm, uint32_t H_prime_total,
uint32_t N_pusch_symbs, uint8_t *g_bits, srslte_uci_bit_t *ri_bits, uint32_t nof_ri_bits,
uint16_t *interleaver_buffer, uint8_t *temp_buffer, uint32_t buffer_sz)
{
uint32_t rows = H_prime_total/N_pusch_symbs;
uint32_t cols = N_pusch_symbs;
/* Compute the interleaving function on-the-fly, because it depends on number of RI bits
* Profiling show that the computation of this matrix is neglegible.
*/
uint32_t idx = 0;
for(uint32_t j=0; j<rows; j++) {
for(uint32_t i=0; i<cols; i++) {
for(uint32_t k=0; k<Qm; k++) {
if (temp_buffer[j*Qm + i*rows*Qm + k]) {
interleaver_buffer[j*Qm + i*rows*Qm + k] = 0;
} else {
if (j*Qm + i*rows*Qm + k < buffer_sz) {
interleaver_buffer[j*Qm + i*rows*Qm + k] = idx;
deinterleaver_buffer[idx] = j*Qm + i*rows*Qm + k;
idx++;
} else {
fprintf(stderr, "Error computing ULSCH interleaver. Position %d exceeds buffer size %d\n", j*Qm + i*rows*Qm + k, buffer_sz);
}
}
}
// Reset temp_buffer because will be reused next time
if (nof_ri_bits > 0) {
for (uint32_t i=0;i<nof_ri_bits;i++) {
ri_present[ri_bits[i].position] = 0;
}
}
}
srslte_vec_fprint_s(stdout, interleaver_buffer, H_prime_total*Qm);
srslte_vec_fprint_s(stdout, deinterleaver_buffer, H_prime_total*Qm);
srslte_bit_interleave(q_bits, g_bits, deinterleaver_buffer, H_prime_total*Qm);
/* 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)
{
// 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);
}
int srslte_ulsch_decode(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer,
int16_t *e_bits, uint8_t *data)
int16_t *q_bits, int16_t *g_bits, uint8_t *data)
{
// Interleave UL-SCH (and RI and CQI)
ulsch_deinterleave(e_bits, Qm, nb_q/Qm, cfg->nbits.nof_symb, q_bits, q->ack_ri_bits, Q_prime_ri*Qm,
q->ul_interleaver, q->temp_g_bits, SRSLTE_MAX_PRB*12*12*12);
uint32_t Q_prime_ri = 0;
uint32_t nb_q = cfg->nbits.nof_bits;
uint32_t Qm = cfg->grant.Qm;
// Interleave UL-SCH (and RI and CQI)
ulsch_deinterleave(q_bits, Qm, nb_q/Qm, cfg->nbits.nof_symb, g_bits, q->ack_ri_bits, Q_prime_ri*Qm,
q->temp_g_bits, q->ul_interleaver);
srslte_vec_fprint_f(stdout, q->temp_g_bits, nb_q);
printf("g_bits=[");
for (int i=0;i<nb_q;i++) {
printf("%d, ", g_bits[i]>0);
}
printf("];\n");
decode_tb(q, softbuffer, &cfg->cb_segm,
return decode_tb(q, softbuffer, &cfg->cb_segm,
cfg->grant.Qm, cfg->rv, cfg->nbits.nof_bits,
e_bits, data);
g_bits, data);
}
int srslte_ulsch_encode(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer,
@ -675,11 +651,12 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q,
uint8_t kk[10000];
srslte_bit_unpack_vector(g_bits, kk, nb_q);
srslte_vec_save_file("g_bits_tx", kk, nb_q);
printf("g_bits_tx=");
srslte_vec_fprint_b(stdout, kk, nb_q);
// Interleave UL-SCH (and RI and CQI)
ulsch_interleave(g_bits, Qm, nb_q/Qm, cfg->nbits.nof_symb, q_bits, q->ack_ri_bits, Q_prime_ri*Qm,
q->ul_interleaver, q->temp_g_bits, SRSLTE_MAX_PRB*12*12*12);
q->temp_g_bits, q->ul_interleaver);
// Encode (and interleave) ACK
if (uci_data.uci_ack_len > 0) {

Loading…
Cancel
Save