new AVX2 decoder working over the air

master
Ismael Gomez 7 years ago
parent f00ea8c8ed
commit e717ccf73a

@ -460,7 +460,7 @@ void map_avx_gamma(map_gen_t * h, int16_t *input, int16_t *app, int16_t *parity,
} }
if (long_cb%16) { if (long_cb%16) {
map_sse_gamma_single((int16_t*) resPtr, (int16_t*) appPtr, (int16_t*) inPtr, (int16_t*) paPtr); map_sse_gamma_single((int16_t*) resPtr, (int16_t*) inPtr, (int16_t*) appPtr, (int16_t*) paPtr);
} }
for (int i=long_cb;i<long_cb+3;i++) { for (int i=long_cb;i<long_cb+3;i++) {

@ -344,7 +344,7 @@ void srslte_tdec_simd_iteration(srslte_tdec_simd_t * h, int16_t * input[SRSLTE_T
uint16_t *deinter = h->interleaver[h->current_cbidx].reverse; uint16_t *deinter = h->interleaver[h->current_cbidx].reverse;
for (int i=0;i<nof_cb;i++) { for (int i=0;i<nof_cb;i++) {
if (h->n_iter[i] == 0) { if (h->n_iter[i] == 0 && input[i]) {
deinterleave_input_simd(h, input[i], i, long_cb); deinterleave_input_simd(h, input[i], i, long_cb);
} }
} }

@ -315,14 +315,13 @@ bool decode_tb_cb(srslte_sch_t *q,
srslte_softbuffer_rx_t *softbuffer, srslte_cbsegm_t *cb_segm, srslte_softbuffer_rx_t *softbuffer, srslte_cbsegm_t *cb_segm,
uint32_t Qm, uint32_t rv, uint32_t nof_e_bits, uint32_t Qm, uint32_t rv, uint32_t nof_e_bits,
int16_t *e_bits, uint8_t *data, int16_t *e_bits, uint8_t *data,
uint32_t cb_size_group, uint8_t parity[3]) uint32_t cb_size_group)
{ {
bool cb_map[SRSLTE_MAX_CODEBLOCKS]; bool cb_map[SRSLTE_MAX_CODEBLOCKS];
bzero(cb_map, sizeof(bool)*SRSLTE_MAX_CODEBLOCKS);
uint32_t cb_idx[SRSLTE_TDEC_NPAR]; uint32_t cb_idx[SRSLTE_TDEC_NPAR];
bool cb_in_use[SRSLTE_TDEC_NPAR];
int16_t *decoder_input[SRSLTE_TDEC_NPAR]; int16_t *decoder_input[SRSLTE_TDEC_NPAR];
uint32_t nof_cb = cb_size_group?cb_segm->C2:cb_segm->C1; uint32_t nof_cb = cb_size_group?cb_segm->C2:cb_segm->C1;
@ -342,6 +341,12 @@ bool decode_tb_cb(srslte_sch_t *q,
for (int i=0;i<SRSLTE_TDEC_NPAR;i++) { for (int i=0;i<SRSLTE_TDEC_NPAR;i++) {
cb_idx[i] = i+first_cb; cb_idx[i] = i+first_cb;
cb_in_use[i] = false;
decoder_input[i] = NULL;
}
for (int i=0;i<nof_cb;i++) {
cb_map[i] = false;
} }
srslte_tdec_reset(&q->decoder, cb_len); srslte_tdec_reset(&q->decoder, cb_len);
@ -354,12 +359,13 @@ bool decode_tb_cb(srslte_sch_t *q,
// Unratematch the codeblocks left to decode // Unratematch the codeblocks left to decode
for (int i=0;i<npar;i++) { for (int i=0;i<npar;i++) {
// Find a not processed CB if (!cb_in_use[i] && i < remaining_cb) {
// Find an unprocessed CB
cb_idx[i]=first_cb; cb_idx[i]=first_cb;
while(cb_idx[i]<first_cb+nof_cb && cb_map[cb_idx[i]]) { while(cb_idx[i]<first_cb+nof_cb-1 && cb_map[cb_idx[i]]) {
cb_idx[i]++; cb_idx[i]++;
} }
cb_in_use[i] = true;
cb_map[cb_idx[i]] = true; cb_map[cb_idx[i]] = true;
uint32_t rp = cb_idx[i]*n_e; uint32_t rp = cb_idx[i]*n_e;
@ -378,6 +384,7 @@ bool decode_tb_cb(srslte_sch_t *q,
decoder_input[i] = softbuffer->buffer_f[cb_idx[i]]; decoder_input[i] = softbuffer->buffer_f[cb_idx[i]];
} }
}
// Run 1 iteration for up to TDEC_NPAR codeblocks // Run 1 iteration for up to TDEC_NPAR codeblocks
if (SRSLTE_TDEC_NPAR > 1) { if (SRSLTE_TDEC_NPAR > 1) {
@ -385,8 +392,11 @@ bool decode_tb_cb(srslte_sch_t *q,
} }
srslte_tdec_iteration_par(&q->decoder, decoder_input, npar, cb_len); srslte_tdec_iteration_par(&q->decoder, decoder_input, npar, cb_len);
q->nof_iterations = srslte_tdec_get_nof_iterations_cb(&q->decoder, 0);
// Decide output bits and compute CRC // Decide output bits and compute CRC
for (int i=0;i<npar;i++) { for (int i=0;i<npar;i++) {
if (cb_in_use[i]) {
srslte_tdec_decision_byte_par_cb(&q->decoder, q->cb_in, i, cb_len); srslte_tdec_decision_byte_par_cb(&q->decoder, q->cb_in, i, cb_len);
uint32_t len_crc; uint32_t len_crc;
@ -403,29 +413,23 @@ bool decode_tb_cb(srslte_sch_t *q,
// CRC is OK // CRC is OK
if (!srslte_crc_checksum_byte(crc_ptr, q->cb_in, len_crc)) { if (!srslte_crc_checksum_byte(crc_ptr, q->cb_in, len_crc)) {
uint32_t wp = cb_idx[i]*rlen; memcpy(&data[(cb_idx[i]*rlen)/8], q->cb_in, rlen/8 * sizeof(uint8_t));
// If it's not the last CB, copy data to another buffer and remove CRC */
if (cb_idx[i] < cb_segm->C - 1) {
memcpy(&data[wp/8], q->cb_in, rlen/8 * sizeof(uint8_t));
// If it's the last CB Append Transport Block parity bits to the last CB
} else {
memcpy(&data[wp/8], q->cb_in, (rlen - 24)/8 * sizeof(uint8_t));
memcpy(parity, &q->cb_in[(rlen - 24)/8], 3 * sizeof(uint8_t));
}
// Reset number of iterations for that CB in the decoder // Reset number of iterations for that CB in the decoder
srslte_tdec_reset_cb(&q->decoder, i); srslte_tdec_reset_cb(&q->decoder, i);
remaining_cb--; remaining_cb--;
cb_in_use[i] = false;
// CRC is error and exceeded maximum iterations for this CB. // CRC is error and exceeded maximum iterations for this CB.
// Early stop the whole transport block. // Early stop the whole transport block.
} else if (srslte_tdec_get_nof_iterations_cb(&q->decoder, i) >= q->max_iterations) { } else if (srslte_tdec_get_nof_iterations_cb(&q->decoder, i) >= q->max_iterations) {
INFO("CB %d: Error. TB is erroneous.\n", cb_idx[i]); INFO("CB %d: Error. CB is erroneous. remaining_cb=%d, i=%d, first_cb=%d, nof_cb=%d, npar=%d\n",
cb_idx[i], remaining_cb, i, first_cb, nof_cb, npar);
return false; return false;
} }
} }
} }
}
return true; return true;
} }
@ -470,14 +474,17 @@ static int decode_tb(srslte_sch_t *q,
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
uint8_t parity[3] = {0, 0, 0};
bool crc_ok = true; bool crc_ok = true;
uint32_t nof_cb_groups = cb_segm->C2>0?2:1; uint32_t nof_cb_groups = cb_segm->C2>0?2:1;
data[cb_segm->tbs/8+0] = 0;
data[cb_segm->tbs/8+1] = 0;
data[cb_segm->tbs/8+2] = 0;
// Process Codeblocks in groups of equal CB size to parallelize according to SRSLTE_TDEC_NPAR // Process Codeblocks in groups of equal CB size to parallelize according to SRSLTE_TDEC_NPAR
for (uint32_t i=0;i<nof_cb_groups && crc_ok;i++) { for (uint32_t i=0;i<nof_cb_groups && crc_ok;i++) {
crc_ok = decode_tb_cb(q, softbuffer, cb_segm, Qm, rv, nof_e_bits, e_bits, data, i, parity); crc_ok = decode_tb_cb(q, softbuffer, cb_segm, Qm, rv, nof_e_bits, e_bits, data, i);
} }
if (crc_ok) { if (crc_ok) {
@ -488,7 +495,9 @@ static int decode_tb(srslte_sch_t *q,
par_rx = srslte_crc_checksum_byte(&q->crc_tb, data, cb_segm->tbs); par_rx = srslte_crc_checksum_byte(&q->crc_tb, data, cb_segm->tbs);
// check parity bits // check parity bits
par_tx = ((uint32_t) parity[0])<<16 | ((uint32_t) parity[1])<<8 | ((uint32_t) parity[2]); par_tx = ((uint32_t) data[cb_segm->tbs/8+0])<<16 |
((uint32_t) data[cb_segm->tbs/8+1])<<8 |
((uint32_t) data[cb_segm->tbs/8+2]);
if (!par_rx) { if (!par_rx) {
INFO("Warning: Received all-zero transport block\n\n",0); INFO("Warning: Received all-zero transport block\n\n",0);

Loading…
Cancel
Save