Added PUSCH ACK decoder and test

master
Xavier Arteaga 7 years ago committed by Ismael Gomez
parent 709787b581
commit 91fe032276

@ -132,7 +132,8 @@ SRSLTE_API int srslte_uci_decode_ack(srslte_pusch_cfg_t *cfg,
uint32_t H_prime_total,
uint32_t O_cqi,
srslte_uci_bit_t *ack_bits,
uint8_t *data);
uint8_t acks[2],
uint32_t nof_acks);
SRSLTE_API int srslte_uci_encode_ri(srslte_pusch_cfg_t *cfg,
uint8_t data,

@ -657,14 +657,17 @@ int srslte_ulsch_uci_decode_ri_ack(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srs
// Deinterleave and decode HARQ bits
if (uci_data->uci_ack_len > 0) {
uint8_t acks[2] = {0, 0};
float beta = beta_harq_offset[cfg->uci_cfg.I_offset_ack];
if (cfg->cb_segm.tbs == 0) {
beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi];
}
ret = srslte_uci_decode_ack(cfg, q_bits, c_seq, beta, nb_q/Qm, uci_data->uci_cqi_len, q->ack_ri_bits, &uci_data->uci_ack);
ret = srslte_uci_decode_ack(cfg, q_bits, c_seq, beta, nb_q/Qm, uci_data->uci_cqi_len, q->ack_ri_bits, acks, uci_data->uci_ack_len);
if (ret < 0) {
return ret;
}
uci_data->uci_ack = acks[0];
uci_data->uci_ack_2 = acks[1];
Q_prime_ack = (uint32_t) ret;
// Set zeros to HARQ bits

@ -190,14 +190,15 @@ int main(int argc, char **argv) {
bzero(&uci_data_tx, sizeof(srslte_uci_data_t));
uci_data_tx.uci_cqi_len = 4;
uci_data_tx.uci_ri_len = 0;
uci_data_tx.uci_ack_len = 0;
uci_data_tx.uci_ack_len = 2;
memcpy(&uci_data_rx, &uci_data_tx, sizeof(srslte_uci_data_t));
for (uint32_t i=0;i<20;i++) {
uci_data_tx.uci_cqi [i] = 1;
}
uci_data_tx.uci_ri = 1;
uci_data_tx.uci_ack = 1;
uci_data_tx.uci_ri = 1;
uci_data_tx.uci_ack = 1;
uci_data_tx.uci_ack_2 = 1;
uint32_t nof_re = SRSLTE_NRE*cell.nof_prb*2*SRSLTE_CP_NSYMB(cell.cp);
sf_symbols = srslte_vec_malloc(sizeof(cf_t) * nof_re);
@ -268,11 +269,19 @@ int main(int argc, char **argv) {
if (uci_data_tx.uci_ack_len) {
if (uci_data_tx.uci_ack != uci_data_rx.uci_ack) {
printf("UCI ACK bit error: %d != %d\n", uci_data_tx.uci_ack, uci_data_rx.uci_ack);
ret = SRSLTE_ERROR;
}
}
if (uci_data_tx.uci_ack_len > 1) {
if (uci_data_tx.uci_ack_2 != uci_data_rx.uci_ack_2) {
printf("UCI ACK 2 bit error: %d != %d\n", uci_data_tx.uci_ack_2, uci_data_rx.uci_ack_2);
ret = SRSLTE_ERROR;
}
}
if (uci_data_tx.uci_ri_len) {
if (uci_data_tx.uci_ri != uci_data_rx.uci_ri) {
printf("UCI RI bit error: %d != %d\n", uci_data_tx.uci_ri, uci_data_rx.uci_ri);
ret = SRSLTE_ERROR;
}
}
if (uci_data_tx.uci_cqi_len) {

@ -560,15 +560,35 @@ static void encode_ri_ack(uint8_t data, srslte_uci_bit_type_t q_encoded_bits[6],
}
}
static int32_t decode_ri_ack(int16_t *q_bits, uint8_t *c_seq, srslte_uci_bit_t *pos)
static void decode_ri_ack(int16_t *q_bits, uint8_t *c_seq, srslte_uci_bit_t *pos, uint32_t Qm, int32_t data[2], uint32_t nof_data)
{
uint32_t p0 = pos[0].position;
uint32_t p1 = pos[1].position;
uint32_t q0 = c_seq[p0]?q_bits[p0]:-q_bits[p0];
uint32_t q1 = c_seq[p0]?q_bits[p1]:-q_bits[p1];
if (nof_data == 1) {
uint32_t p0 = pos[0].position;
uint32_t p1 = pos[1].position;
int32_t q0 = c_seq[p0] ? q_bits[p0] : -q_bits[p0];
int32_t q1 = c_seq[p0] ? q_bits[p1] : -q_bits[p1];
return -(q0+q1);
data[0] -= q0 + q1;
} else {
uint32_t p0 = pos[Qm * 0 + 0].position;
uint32_t p1 = pos[Qm * 0 + 1].position;
uint32_t p2 = pos[Qm * 1 + 6].position;
uint32_t p3 = pos[Qm * 1 + 7].position;
uint32_t p4 = pos[Qm * 2 + 12].position;
uint32_t p5 = pos[Qm * 2 + 13].position;
int32_t q0 = c_seq[p0] ? q_bits[p0] : -q_bits[p0];
int32_t q1 = c_seq[p1] ? q_bits[p1] : -q_bits[p1];
int32_t q2 = c_seq[p2] ? q_bits[p2] : -q_bits[p2];
int32_t q3 = c_seq[p3] ? q_bits[p3] : -q_bits[p3];
int32_t q4 = c_seq[p4] ? q_bits[p4] : -q_bits[p4];
int32_t q5 = c_seq[p5] ? q_bits[p5] : -q_bits[p5];
data[0] -= q0 + q3;
data[1] -= q1 + q4;
data[2] -= q2 + q5;
}
}
@ -577,25 +597,27 @@ static int32_t decode_ri_ack(int16_t *q_bits, uint8_t *c_seq, srslte_uci_bit_t *
*/
int srslte_uci_decode_ack(srslte_pusch_cfg_t *cfg, int16_t *q_bits, uint8_t *c_seq,
float beta, uint32_t H_prime_total,
uint32_t O_cqi, srslte_uci_bit_t *ack_bits, uint8_t *data)
uint32_t O_cqi, srslte_uci_bit_t *ack_bits, uint8_t acks[2], uint32_t nof_acks)
{
int32_t rx_ack = 0;
int32_t acks_sum[3] = {0, 0, 0};
if (beta < 0) {
fprintf(stderr, "Error beta is reserved\n");
return -1;
}
uint32_t Qprime = Q_prime_ri_ack(cfg, 1, O_cqi, beta);
uint32_t Qprime = Q_prime_ri_ack(cfg, nof_acks, O_cqi, beta);
// Use the same interleaver function to get the HARQ bit position
for (uint32_t i=0;i<Qprime;i++) {
for (uint32_t i = 0; i < Qprime; i += (nof_acks > 1) ? 3 : 1) {
uci_ulsch_interleave_ack_gen(i, cfg->grant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, &ack_bits[cfg->grant.Qm*i]);
rx_ack += (int32_t) decode_ri_ack(q_bits, c_seq, ack_bits);
decode_ri_ack(q_bits, c_seq, ack_bits, cfg->grant.Qm, acks_sum, nof_acks);
}
if (data) {
*data = rx_ack>0;
if (acks) {
acks[0] = (uint8_t)(acks_sum[0] > 0);
acks[1] = (uint8_t)(acks_sum[1] > 0);
// TODO: Do something with acks_sum[2]
}
return (int) Qprime;
}
@ -644,7 +666,7 @@ int srslte_uci_decode_ri(srslte_pusch_cfg_t *cfg, int16_t *q_bits, uint8_t *c_se
// Use the same interleaver function to get the HARQ bit position
for (uint32_t i=0;i<Qprime;i++) {
uci_ulsch_interleave_ri_gen(i, cfg->grant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, &ri_bits[cfg->grant.Qm*i]);
rx_ri += (int32_t) decode_ri_ack(q_bits, c_seq, ri_bits);
decode_ri_ack(q_bits, c_seq, ri_bits, cfg->grant.Qm, &rx_ri, 1);
}
if (data) {

Loading…
Cancel
Save