Added CRC-based early stopping to Turbo decoder

master
ismagom 11 years ago
parent 85fc5adc01
commit 3dfb1824b4

@ -48,7 +48,7 @@ int cuhd_recv_wrapper(void *h, void *data, uint32_t nsamples) {
} }
/* Setup USRP or input file */ /* Setup USRP or input file */
int iodev_init(iodev_t *q, iodev_cfg_t *config) { int iodev_init(iodev_t *q, iodev_cfg_t *config, uint32_t file_sf_len) {
if (config->input_file_name) { if (config->input_file_name) {
if (filesource_init(&q->fsrc, config->input_file_name, COMPLEX_FLOAT_BIN)) { if (filesource_init(&q->fsrc, config->input_file_name, COMPLEX_FLOAT_BIN)) {
@ -61,7 +61,7 @@ int iodev_init(iodev_t *q, iodev_cfg_t *config) {
} }
q->mode = FILESOURCE; q->mode = FILESOURCE;
q->sf_len = 1920; q->sf_len = file_sf_len;
} else { } else {
#ifndef DISABLE_UHD #ifndef DISABLE_UHD

@ -74,7 +74,8 @@ typedef struct LIBLTE_API {
LIBLTE_API int iodev_init(iodev_t *q, LIBLTE_API int iodev_init(iodev_t *q,
iodev_cfg_t *config); iodev_cfg_t *config,
uint32_t file_sf_len);
LIBLTE_API void iodev_free(iodev_t *q); LIBLTE_API void iodev_free(iodev_t *q);

@ -359,7 +359,10 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
pdsch_encode(&pdsch, data, sf_symbols, sf_idx, &harq_process, ra_dl.rv_idx); if (pdsch_encode(&pdsch, data, sf_symbols, sf_idx, &harq_process, ra_dl.rv_idx)) {
fprintf(stderr, "Error encoding PDSCH\n");
exit(-1);
}
/* Transform to OFDM symbols */ /* Transform to OFDM symbols */
lte_ifft_run_sf(&ifft, sf_buffer, output_buffer); lte_ifft_run_sf(&ifft, sf_buffer, output_buffer);

@ -165,11 +165,18 @@ int main(int argc, char **argv) {
pbch_mib_t mib; pbch_mib_t mib;
bool printed_sib = false; bool printed_sib = false;
int rlen; int rlen;
int symbol_sz;
parse_args(&prog_args, argc, argv); parse_args(&prog_args, argc, argv);
if (iodev_init(&iodev, &prog_args.io_config)) { symbol_sz = lte_symbol_sz(prog_args.nof_prb_file);
fprintf(stderr, "Error initiating input device\n"); if (symbol_sz > 0) {
if (iodev_init(&iodev, &prog_args.io_config, SF_LEN(symbol_sz, CPNORM))) {
fprintf(stderr, "Error initiating input device\n");
exit(-1);
}
} else {
fprintf(stderr, "Invalid number of PRB %d\n", prog_args.nof_prb_file);
exit(-1); exit(-1);
} }
@ -242,9 +249,10 @@ int main(int argc, char **argv) {
printed_sib = true; printed_sib = true;
} }
if (!(sf_cnt % 10)) { if (!(sf_cnt % 10)) {
printf("RSSI: %+.2f dBm, CFO: %+.4f KHz, SFO: %+.4f Khz, TimeOffset: %4d, Errors: %4d/%4d, BLER: %.1e\r", printf("RSSI: %+.2f dBm, CFO: %+.4f KHz, SFO: %+.4f Khz, NOI: %.2f Errors: %4d/%4d, BLER: %.1e\r",
20*log10f(agc_get_rssi(&iodev.sframe.agc))+30, 20*log10f(agc_get_rssi(&iodev.sframe.agc))+30,
ue_sync_get_cfo(&iodev.sframe)/1000, ue_sync_get_sfo(&iodev.sframe)/1000, iodev.sframe.peak_idx, ue_sync_get_cfo(&iodev.sframe)/1000, ue_sync_get_sfo(&iodev.sframe)/1000,
pdsch_average_noi(&ue_dl.pdsch),
(int) ue_dl.pkt_errors, (int) ue_dl.pkts_total, (float) ue_dl.pkt_errors / ue_dl.pkts_total); (int) ue_dl.pkt_errors, (int) ue_dl.pkts_total, (float) ue_dl.pkt_errors / ue_dl.pkts_total);
fflush(stdout); fflush(stdout);

@ -43,7 +43,7 @@
#include "liblte/phy/phch/dci.h" #include "liblte/phy/phch/dci.h"
#include "liblte/phy/phch/regs.h" #include "liblte/phy/phch/regs.h"
#define TDEC_ITERATIONS 3 #define TDEC_MAX_ITERATIONS 6
typedef _Complex float cf_t; typedef _Complex float cf_t;
@ -75,6 +75,9 @@ typedef struct LIBLTE_API {
uint32_t max_symbols; uint32_t max_symbols;
bool rnti_is_set; bool rnti_is_set;
uint16_t rnti; uint16_t rnti;
uint32_t nof_iterations;
uint64_t average_nof_iterations_n;
float average_nof_iterations;
/* buffers */ /* buffers */
// void buffers are shared for tx and rx // void buffers are shared for tx and rx
@ -128,6 +131,10 @@ LIBLTE_API int pdsch_decode(pdsch_t *q,
pdsch_harq_t *harq_process, pdsch_harq_t *harq_process,
uint32_t rv_idx); uint32_t rv_idx);
LIBLTE_API float pdsch_average_noi(pdsch_t *q);
LIBLTE_API uint32_t pdsch_last_noi(pdsch_t *q);
LIBLTE_API int pdsch_get(pdsch_t *q, LIBLTE_API int pdsch_get(pdsch_t *q,
cf_t *sf_symbols, cf_t *sf_symbols,
cf_t *pdsch_symbols, cf_t *pdsch_symbols,

@ -183,7 +183,7 @@ int pdsch_init(pdsch_t *q, lte_cell_t cell) {
ret = LIBLTE_ERROR; ret = LIBLTE_ERROR;
q->cell = cell; q->cell = cell;
q->average_nof_iterations_n = 0;
q->max_symbols = q->cell.nof_prb * MAX_PDSCH_RE(q->cell.cp); q->max_symbols = q->cell.nof_prb * MAX_PDSCH_RE(q->cell.cp);
INFO("Init PDSCH: %d ports %d PRBs, max_symbols: %d\n", q->cell.nof_ports, INFO("Init PDSCH: %d ports %d PRBs, max_symbols: %d\n", q->cell.nof_ports,
@ -459,6 +459,15 @@ int pdsch_harq_setup(pdsch_harq_t *p, ra_mcs_t mcs, ra_prb_t *prb_alloc) {
} }
float pdsch_average_noi(pdsch_t *q) {
return q->average_nof_iterations;
}
uint32_t pdsch_last_noi(pdsch_t *q) {
return q->nof_iterations;
}
/* Decode a transport block according to 36.212 5.3.2 /* Decode a transport block according to 36.212 5.3.2
* *
*/ */
@ -516,17 +525,42 @@ int pdsch_decode_tb(pdsch_t *q, char *data, uint32_t tbs, uint32_t nb_e,
return LIBLTE_ERROR; return LIBLTE_ERROR;
} }
/* Turbo Decoding */ /* Turbo Decoding with CRC-based early stopping */
tdec_run_all(&q->decoder, (float*) q->cb_out, q->cb_in, TDEC_ITERATIONS, q->nof_iterations = 0;
cb_len); bool early_stop = false;
uint32_t len_crc;
if (harq_process->cb_segm.C > 1) { char *cb_in_ptr;
crc_t *crc_ptr;
tdec_reset(&q->decoder, cb_len);
do {
tdec_iteration(&q->decoder, (float*) q->cb_out, cb_len);
q->nof_iterations++;
if (harq_process->cb_segm.C > 1) {
len_crc = cb_len;
cb_in_ptr = q->cb_in;
crc_ptr = &q->crc_cb;
} else {
len_crc = tbs+24;
cb_in_ptr = &q->cb_in[F];
crc_ptr = &q->crc_tb;
}
/* Check Codeblock CRC and stop early if incorrect */ /* Check Codeblock CRC and stop early if incorrect */
if (crc_checksum(&q->crc_cb, q->cb_in, cb_len)) { if (!crc_checksum(crc_ptr, cb_in_ptr, len_crc)) {
INFO("Error in CB#%d\n",i); early_stop = true;
return LIBLTE_ERROR;
} }
}
} while (q->nof_iterations < TDEC_MAX_ITERATIONS && !early_stop);
tdec_decision(&q->decoder, q->cb_in, cb_len);
q->average_nof_iterations = EXPAVERAGE((float) q->nof_iterations,
q->average_nof_iterations,
q->average_nof_iterations_n);
q->average_nof_iterations_n++;
/* Copy data to another buffer, removing the Codeblock CRC */ /* Copy data to another buffer, removing the Codeblock CRC */
if (i < harq_process->cb_segm.C - 1) { if (i < harq_process->cb_segm.C - 1) {
@ -534,6 +568,7 @@ int pdsch_decode_tb(pdsch_t *q, char *data, uint32_t tbs, uint32_t nb_e,
} else { } else {
DEBUG("Last CB, appending parity: %d to %d from %d and 24 from %d\n", DEBUG("Last CB, appending parity: %d to %d from %d and 24 from %d\n",
rlen - F - 24, wp, F, rlen - 24); rlen - F - 24, wp, F, rlen - 24);
/* Append Transport Block parity bits to the last CB */ /* Append Transport Block parity bits to the last CB */
memcpy(&data[wp], &q->cb_in[F], (rlen - F - 24) * sizeof(char)); memcpy(&data[wp], &q->cb_in[F], (rlen - F - 24) * sizeof(char));
memcpy(parity, &q->cb_in[rlen - 24], 24 * sizeof(char)); memcpy(parity, &q->cb_in[rlen - 24], 24 * sizeof(char));
@ -553,6 +588,7 @@ int pdsch_decode_tb(pdsch_t *q, char *data, uint32_t tbs, uint32_t nb_e,
par_tx = bit_unpack(&p_parity, 24); par_tx = bit_unpack(&p_parity, 24);
if (!par_rx) { if (!par_rx) {
vec_fprint_hex(stdout, data, tbs);
printf("\n\tCAUTION!! Received all-zero transport block\n\n"); printf("\n\tCAUTION!! Received all-zero transport block\n\n");
} }

Loading…
Cancel
Save