From 3f3e045511f6fddd7b838e75aed485c1543f0274 Mon Sep 17 00:00:00 2001 From: ismagom Date: Tue, 22 Sep 2015 21:20:36 +0100 Subject: [PATCH] Integrated LUT rate recovery in dlsch decoding. All tests ok --- matlab/tests/dlsch_test.m | 2 +- srslte/include/srslte/fec/cbsegm.h | 2 + srslte/include/srslte/fec/rm_turbo.h | 6 +- srslte/include/srslte/fec/softbuffer.h | 4 +- srslte/include/srslte/phch/sch.h | 2 +- srslte/include/srslte/utils/debug.h | 2 +- srslte/lib/fec/src/cbsegm.c | 3 + srslte/lib/fec/src/rm_turbo.c | 218 ++++++++++++--------- srslte/lib/fec/src/softbuffer.c | 12 +- srslte/lib/fec/src/tc_interl_lte.c | 2 - srslte/lib/fec/test/CMakeLists.txt | 9 +- srslte/lib/fec/test/rm_turbo_test.c | 250 ++++++++++--------------- srslte/lib/fec/test/turbocoder_test.c | 28 +-- srslte/lib/modem/test/CMakeLists.txt | 24 +-- srslte/lib/phch/src/pdsch.c | 9 +- srslte/lib/phch/src/sch.c | 72 ++++--- srslte/lib/phch/test/CMakeLists.txt | 6 +- srslte/lib/phch/test/pdsch_test.c | 3 +- 18 files changed, 322 insertions(+), 332 deletions(-) diff --git a/matlab/tests/dlsch_test.m b/matlab/tests/dlsch_test.m index aa975a379..c3b19a98b 100644 --- a/matlab/tests/dlsch_test.m +++ b/matlab/tests/dlsch_test.m @@ -1,7 +1,7 @@ enbConfig=struct('NCellID',1,'CyclicPrefix','Normal','CellRefP',1); pdschConfig=struct('Modulation','QPSK','RV',0,'TxScheme','Port0'); -addpath('/home/ismael/work/srsLTE/debug/srslte/lib/phch/test') +addpath('/home/ismael/work/srsLTE/build/srslte/lib/phch/test') TBs=40:8:800; e_bits=1000; diff --git a/srslte/include/srslte/fec/cbsegm.h b/srslte/include/srslte/fec/cbsegm.h index 2208770d4..37ef50f57 100644 --- a/srslte/include/srslte/fec/cbsegm.h +++ b/srslte/include/srslte/fec/cbsegm.h @@ -41,6 +41,8 @@ uint32_t C; uint32_t K1; uint32_t K2; + uint32_t K1_idx; + uint32_t K2_idx; uint32_t C1; uint32_t C2; uint32_t tbs; diff --git a/srslte/include/srslte/fec/rm_turbo.h b/srslte/include/srslte/fec/rm_turbo.h index 609e93e14..7babcb15c 100644 --- a/srslte/include/srslte/fec/rm_turbo.h +++ b/srslte/include/srslte/fec/rm_turbo.h @@ -78,10 +78,10 @@ SRSLTE_API int srslte_rm_turbo_rx(float *w_buff, uint32_t nof_filler_bits); SRSLTE_API int srslte_rm_turbo_rx_lut(float *input, + float *output, uint32_t in_len, - float *output, - uint32_t out_len, - uint32_t rv_idx, uint32_t cb_idx); + uint32_t cb_idx, + uint32_t rv_idx); /* High-level API */ typedef struct SRSLTE_API { diff --git a/srslte/include/srslte/fec/softbuffer.h b/srslte/include/srslte/fec/softbuffer.h index 22210be5f..609ef6b85 100644 --- a/srslte/include/srslte/fec/softbuffer.h +++ b/srslte/include/srslte/fec/softbuffer.h @@ -42,16 +42,16 @@ typedef struct SRSLTE_API { uint32_t max_cb; - uint32_t buff_size; float **buffer_f; } srslte_softbuffer_rx_t; typedef struct SRSLTE_API { uint32_t max_cb; - uint32_t buff_size; uint8_t **buffer_b; } srslte_softbuffer_tx_t; +#define SOFTBUFFER_SIZE 18600 + SRSLTE_API int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t * q, uint32_t nof_prb); diff --git a/srslte/include/srslte/phch/sch.h b/srslte/include/srslte/phch/sch.h index 99b4c76bd..95e8a9545 100644 --- a/srslte/include/srslte/phch/sch.h +++ b/srslte/include/srslte/phch/sch.h @@ -65,7 +65,7 @@ typedef struct SRSLTE_API { /* buffers */ uint8_t *cb_in; - void *cb_out; + uint8_t *parity_bits; void *e; uint8_t *temp_g_bits; uint32_t *ul_interleaver; diff --git a/srslte/include/srslte/utils/debug.h b/srslte/include/srslte/utils/debug.h index 424bb0ccb..e7151a7cf 100644 --- a/srslte/include/srslte/utils/debug.h +++ b/srslte/include/srslte/utils/debug.h @@ -46,7 +46,7 @@ #include SRSLTE_API void get_time_interval(struct timeval * tdata); -#define SRSLTE_DEBUG_ENABLED 0 +#define SRSLTE_DEBUG_ENABLED 1 SRSLTE_API extern int srslte_verbose; diff --git a/srslte/lib/fec/src/cbsegm.c b/srslte/lib/fec/src/cbsegm.c index 73fcfa874..35be33fc6 100644 --- a/srslte/lib/fec/src/cbsegm.c +++ b/srslte/lib/fec/src/cbsegm.c @@ -75,16 +75,19 @@ int srslte_cbsegm(srslte_cbsegm_t *s, uint32_t tbs) { ret = srslte_cbsegm_cbsize(idx1); if (ret != SRSLTE_ERROR) { s->K1 = (uint32_t) ret; + s->K1_idx = idx1; if (idx1 > 0) { ret = srslte_cbsegm_cbsize(idx1 - 1); } if (ret != SRSLTE_ERROR) { if (s->C == 1) { s->K2 = 0; + s->K2_idx = 0; s->C2 = 0; s->C1 = 1; } else { s->K2 = (uint32_t) ret; + s->K2_idx = idx1-1; s->C2 = (s->C * s->K1 - Bp) / (s->K1 - s->K2); s->C1 = s->C - s->C2; } diff --git a/srslte/lib/fec/src/rm_turbo.c b/srslte/lib/fec/src/rm_turbo.c index 359a6d82c..7c704251f 100644 --- a/srslte/lib/fec/src/rm_turbo.c +++ b/srslte/lib/fec/src/rm_turbo.c @@ -38,7 +38,6 @@ #include "srslte/fec/cbsegm.h" - #define NCOLS 32 #define NROWS_MAX NCOLS @@ -47,10 +46,11 @@ static uint8_t RM_PERM_TC[NCOLS] = { 0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, static uint32_t interleaver_systematic_bits[SRSLTE_NOF_TC_CB_SIZES][6148]; // 4 tail bits static uint32_t interleaver_parity_bits[SRSLTE_NOF_TC_CB_SIZES][2*6148]; +static uint32_t deinterleaver[SRSLTE_NOF_TC_CB_SIZES][4][3*6148]; static uint32_t k0_vec[SRSLTE_NOF_TC_CB_SIZES][4][2]; static bool rm_turbo_tables_generated = false; -uint32_t table_buffer[6144], table_output[6144]; +static uint32_t temp_table1[3*6176], temp_table2[3*6176]; void srslte_rm_turbo_gentable_systematic(uint32_t *table_bits, uint32_t k0_vec[4][2], uint32_t nrows, int ndummy) { @@ -122,6 +122,83 @@ void srslte_rm_turbo_gentable_parity(uint32_t *table_parity, uint32_t k0_vec[4][ } + +void srslte_rm_turbo_gentable_receive(uint32_t *table, uint32_t cb_len, uint32_t rv_idx) +{ + + int nrows = (uint32_t) (cb_len / 3 - 1) / NCOLS + 1; + int ndummy = nrows*NCOLS - cb_len / 3; + if (ndummy < 0) { + ndummy = 0; + } + + /* Undo bit collection. Account for dummy bits */ + int N_cb = 3*nrows*NCOLS; + int k0 = nrows*(2*(uint32_t) ceilf((float) N_cb/(float) (8*nrows))*rv_idx+2); + + int kidx; + int K_p = nrows * NCOLS; + int k = 0, jp=0, j=0; + bool isdummy = false; + int d_i, d_j; + while (k < cb_len) { + jp = (k0 + j) % N_cb; + + if (jp < K_p || !(jp % 2)) { + if (jp >= K_p) { + d_i = ((jp - K_p) / 2) / nrows; + d_j = ((jp - K_p) / 2) % nrows; + } else { + d_i = jp / nrows; + d_j = jp % nrows; + } + if (d_j * NCOLS + RM_PERM_TC[d_i] >= ndummy) { + isdummy = false; + if (d_j * NCOLS + RM_PERM_TC[d_i] - ndummy < 0) { + isdummy = true; + } + } else { + isdummy = true; + } + + } else { + uint32_t jpp = (jp - K_p - 1) / 2; + kidx = (RM_PERM_TC[jpp / nrows] + NCOLS * (jpp % nrows) + 1) % K_p; + if ((kidx - ndummy) < 0) { + isdummy = true; + } else { + isdummy = false; + } + } + + if (!isdummy) { + temp_table1[k] = jp%(3*nrows*NCOLS); + k++; + } + j++; + } + + for (int i = 0; i < cb_len / 3; i++) { + d_i = (i + ndummy) / NCOLS; + d_j = (i + ndummy) % NCOLS; + for (j = 0; j < 3; j++) { + if (j != 2) { + kidx = K_p * j + (j + 1) * (RM_PERM_TC[d_j] * nrows + d_i); + } else { + k = (i + ndummy - 1) % K_p; + if (k < 0) + k += K_p; + kidx = (k / NCOLS + nrows * RM_PERM_TC[k % NCOLS]) % K_p; + kidx = 2 * kidx + K_p + 1; + } + temp_table2[kidx] = 3*i+j; + } + } + for (int i=0;i= K_p) { - d_i = ((jp - K_p) / 2) / nrows; - d_j = ((jp - K_p) / 2) % nrows; - } else { - d_i = jp / nrows; - d_j = jp % nrows; - } - if (d_j * NCOLS + RM_PERM_TC[d_i] >= ndummy) { - isdummy = false; - if (d_j * NCOLS + RM_PERM_TC[d_i] - ndummy < 0) { - isdummy = true; - } - } else { - isdummy = true; - } - - } else { - uint32_t jpp = (jp - K_p - 1) / 2; - kidx = (RM_PERM_TC[jpp / nrows] + NCOLS * (jpp % nrows) + 1) % K_p; - if ((kidx - ndummy) < 0) { - isdummy = true; - } else { - isdummy = false; - } - } - - if (!isdummy) { - table_buffer[k] = jp%(3*nrows*NCOLS); - k++; - } - j++; - } - - for (int i = 0; i < cb_len / 3; i++) { - d_i = (i + ndummy) / NCOLS; - d_j = (i + ndummy) % NCOLS; - for (j = 0; j < 3; j++) { - if (j != 2) { - kidx = K_p * j + (j + 1) * (RM_PERM_TC[d_j] * nrows + d_i); - } else { - k = (i + ndummy - 1) % K_p; - if (k < 0) - k += K_p; - kidx = (k / NCOLS + nrows * RM_PERM_TC[k % NCOLS]) % K_p; - kidx = 2 * kidx + K_p + 1; - } - table_output[kidx] = 3*i+j; - } - } -} - -int srslte_rm_turbo_rx_lut(float *input, uint32_t in_len, float *output, uint32_t out_len, uint32_t rv_idx, uint32_t cb_idx) -{ - - for (int i=0;ibuff_size = 18600; for (uint32_t i=0;imax_cb;i++) { - q->buffer_f[i] = srslte_vec_malloc(sizeof(float) * q->buff_size); + q->buffer_f[i] = srslte_vec_malloc(sizeof(float) * SOFTBUFFER_SIZE); if (!q->buffer_f[i]) { perror("malloc"); return SRSLTE_ERROR; @@ -108,9 +107,7 @@ void srslte_softbuffer_rx_reset_cb(srslte_softbuffer_rx_t *q, uint32_t nof_cb) { } for (uint32_t i=0;ibuffer_f[i]) { - for (uint32_t j=0;jbuff_size;j++) { - q->buffer_f[i][j] = SRSLTE_RX_NULL; - } + bzero(q->buffer_f[i], SOFTBUFFER_SIZE*sizeof(float)); } } } @@ -137,9 +134,8 @@ int srslte_softbuffer_tx_init(srslte_softbuffer_tx_t *q, uint32_t nof_prb) { } // FIXME: Use HARQ buffer limitation based on UE category - q->buff_size = 18600; for (uint32_t i=0;imax_cb;i++) { - q->buffer_b[i] = srslte_vec_malloc(sizeof(float) * q->buff_size); + q->buffer_b[i] = srslte_vec_malloc(sizeof(float) * SOFTBUFFER_SIZE); if (!q->buffer_b[i]) { perror("malloc"); return SRSLTE_ERROR; @@ -184,7 +180,7 @@ void srslte_softbuffer_tx_reset_cb(srslte_softbuffer_tx_t *q, uint32_t nof_cb) { } for (i=0;ibuffer_b[i]) { - bzero(q->buffer_b[i], sizeof(uint8_t) * q->buff_size); + bzero(q->buffer_b[i], sizeof(uint8_t) * SOFTBUFFER_SIZE); } } } diff --git a/srslte/lib/fec/src/tc_interl_lte.c b/srslte/lib/fec/src/tc_interl_lte.c index c996f9298..34c0a42eb 100644 --- a/srslte/lib/fec/src/tc_interl_lte.c +++ b/srslte/lib/fec/src/tc_interl_lte.c @@ -86,8 +86,6 @@ int srslte_tc_interl_LTE_gen(srslte_tc_interl_t *h, uint32_t long_cb) { f1 = f1_list[cb_table_idx]; f2 = f2_list[cb_table_idx]; - DEBUG("table_idx: %d, f1: %d, f2: %d\n", cb_table_idx, f1, f2); - h->forward[0] = 0; h->reverse[0] = 0; for (i = 1; i < long_cb; i++) { diff --git a/srslte/lib/fec/test/CMakeLists.txt b/srslte/lib/fec/test/CMakeLists.txt index 3bbcddf48..e02ad9a16 100644 --- a/srslte/lib/fec/test/CMakeLists.txt +++ b/srslte/lib/fec/test/CMakeLists.txt @@ -33,10 +33,8 @@ TARGET_LINK_LIBRARIES(rm_turbo_test srslte) ADD_TEST(rm_conv_test_1 rm_conv_test -t 480 -r 1920) ADD_TEST(rm_conv_test_2 rm_conv_test -t 1920 -r 480) -ADD_TEST(rm_turbo_test_1 rm_turbo_test -t 480 -r 1920 -i 0) -ADD_TEST(rm_turbo_test_2 rm_turbo_test -t 1920 -r 480 -i 1) -ADD_TEST(rm_turbo_test_1 rm_turbo_test -t 480 -r 1920 -i 2) -ADD_TEST(rm_turbo_test_2 rm_turbo_test -t 1920 -r 480 -i 3) +ADD_TEST(rm_turbo_test_1 rm_turbo_test -e 1920) +ADD_TEST(rm_turbo_test_2 rm_turbo_test -e 8192) BuildMex(MEXNAME rm_turbo_rx SOURCES rm_turbo_rx_mex.c LIBRARIES srslte srslte_mex) @@ -55,8 +53,7 @@ BuildMex(MEXNAME turbodecoder SOURCES turbodecoder_test_mex.c LIBRARIES srslte s ADD_EXECUTABLE(turbocoder_test turbocoder_test.c) TARGET_LINK_LIBRARIES(turbocoder_test srslte) -ADD_TEST(turbocoder_test_40 turbocoder_test -l 40) -ADD_TEST(turbocoder_test_6114 turbocoder_test -l 6114) +ADD_TEST(turbocoder_test_all turbocoder_test) ######################################################################## # Viterbi TEST diff --git a/srslte/lib/fec/test/rm_turbo_test.c b/srslte/lib/fec/test/rm_turbo_test.c index f246a8e64..7db03448f 100644 --- a/srslte/lib/fec/test/rm_turbo_test.c +++ b/srslte/lib/fec/test/rm_turbo_test.c @@ -37,33 +37,34 @@ #include "srslte/srslte.h" -int nof_tx_bits = -1, nof_rx_bits = -1; -int nof_filler_bits = -1; -int rv_idx = 0; +int nof_e_bits = -1; +int rv_idx = -1; int cb_idx = -1; uint8_t systematic[6148], parity[2*6148]; uint8_t systematic_bytes[6148/8+1], parity_bytes[2*6148/8+1]; +#define BUFFSZ 6176*3 + +uint8_t bits[3*6144+12]; +uint8_t buff_b[BUFFSZ]; +float buff_f[BUFFSZ]; +float bits_f[3*6144+12]; +float bits2_f[3*6144+12]; + void usage(char *prog) { - printf("Usage: %s -t nof_tx_bits | -c cb_idx -r nof_rx_bits [-i rv_idx -f nof_filler_bits]\n", prog); + printf("Usage: %s -c cb_idx -e nof_e_bits [-i rv_idx]\n", prog); } void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "tcrif")) != -1) { + while ((opt = getopt(argc, argv, "cei")) != -1) { switch (opt) { - case 'f': - nof_filler_bits = atoi(argv[optind]); - break; case 'c': cb_idx = atoi(argv[optind]); break; - case 't': - nof_tx_bits = atoi(argv[optind]); - break; - case 'r': - nof_rx_bits = atoi(argv[optind]); + case 'e': + nof_e_bits = atoi(argv[optind]); break; case 'i': rv_idx = atoi(argv[optind]); @@ -73,178 +74,127 @@ void parse_args(int argc, char **argv) { exit(-1); } } - if (nof_tx_bits == -1 && cb_idx == -1) { - usage(argv[0]); - exit(-1); - } - if (nof_rx_bits == -1) { + if (nof_e_bits == -1) { usage(argv[0]); exit(-1); } } + int main(int argc, char **argv) { int i; - uint8_t *bits, *bits_out, *rm_bits, *rm_bits2, *rm_bits2_bytes, *w_buff_c; - float *rm_symbols, *unrm_symbols, *unrm_symbols2, *w_buff_f; - int nof_errors; - + uint8_t *rm_bits, *rm_bits2, *rm_bits2_bytes; + float *rm_bits_f; + parse_args(argc, argv); srslte_rm_turbo_gentables(); - if (cb_idx != -1) { - nof_tx_bits = 3*srslte_cbsegm_cbsize(cb_idx)+12; - } - - bits = malloc(sizeof(uint8_t) * nof_tx_bits); - if (!bits) { - perror("malloc"); - exit(-1); - } - bits_out = malloc(sizeof(uint8_t) * nof_tx_bits); - if (!bits_out) { - perror("malloc"); - exit(-1); - } - w_buff_c = malloc(sizeof(uint8_t) * nof_tx_bits * 10); - if (!w_buff_c) { + rm_bits_f = malloc(sizeof(float) * nof_e_bits); + if (!rm_bits_f) { perror("malloc"); exit(-1); } - rm_bits = malloc(sizeof(uint8_t) * nof_rx_bits); + rm_bits = malloc(sizeof(uint8_t) * nof_e_bits); if (!rm_bits) { perror("malloc"); exit(-1); } - rm_bits2 = malloc(sizeof(uint8_t) * nof_rx_bits); + rm_bits2 = malloc(sizeof(uint8_t) * nof_e_bits); if (!rm_bits2) { perror("malloc"); exit(-1); } - rm_bits2_bytes = malloc(sizeof(uint8_t) * nof_rx_bits/8 + 1); + rm_bits2_bytes = malloc(sizeof(uint8_t) * nof_e_bits/8 + 1); if (!rm_bits2_bytes) { perror("malloc"); exit(-1); } - rm_symbols = malloc(sizeof(float) * nof_rx_bits); - if (!rm_symbols) { - perror("malloc"); - exit(-1); - } - w_buff_f = malloc(sizeof(float) * nof_rx_bits * 10); - if (!w_buff_f) { - perror("malloc"); - exit(-1); - } - unrm_symbols = malloc(sizeof(float) * nof_tx_bits); - if (!unrm_symbols) { - perror("malloc"); - exit(-1); - } - unrm_symbols2 = malloc(sizeof(float) * nof_tx_bits); - if (!unrm_symbols2) { - perror("malloc"); - exit(-1); - } - - for (i = 0; i < nof_tx_bits; i++) { - bits[i] = rand() % 2; - } - - for (i=0;i 0) { - srslte_rm_turbo_tx(w_buff_c, nof_tx_bits * 10, bits, nof_tx_bits, rm_bits, nof_rx_bits, rv_idx); - } - - for (i=0;i 0) { - bzero(rm_bits2_bytes, nof_rx_bits/8); - srslte_rm_turbo_tx_lut(w_buff_c, systematic_bytes, parity_bytes, rm_bits2_bytes, cb_idx, nof_rx_bits, 0, rv_idx); + uint32_t st=0, end=188; + if (cb_idx != -1) { + st=cb_idx; + end=cb_idx+1; } - - srslte_bit_unpack_vector(rm_bits2_bytes, rm_bits2, nof_rx_bits); - - for (i = 0; i < nof_rx_bits; i++) { - rm_symbols[i] = (float) rm_bits[i] ? 1 : -1; + uint32_t rv_st=0, rv_end=4; + if (rv_idx != -1) { + rv_st=rv_idx; + rv_end=rv_idx+1; } - for (int i=0;i 0) { + srslte_rm_turbo_tx(buff_b, BUFFSZ, bits, long_cb_enc, rm_bits, nof_e_bits, rv_idx); + } + + for (int i=0;i 0) { + bzero(rm_bits2_bytes, nof_e_bits/8); + srslte_rm_turbo_tx_lut(buff_b, systematic_bytes, parity_bytes, rm_bits2_bytes, cb_idx, nof_e_bits, 0, rv_idx); + } + + srslte_bit_unpack_vector(rm_bits2_bytes, rm_bits2, nof_e_bits); + + for (int i=0;i0?1:0; - } - nof_errors = 0; - for (i = 0; i < nof_tx_bits; i++) { - if (bits_out[i] != bits[i]) { - nof_errors++; } } - free(bits); free(rm_bits); - free(rm_symbols); - free(unrm_symbols); - free(bits_out); + free(rm_bits2); + free(rm_bits2_bytes); - if (nof_errors) { - printf("nof_errors=%d\n", nof_errors); - exit(-1); - } - - printf("Ok\n"); exit(0); } diff --git a/srslte/lib/fec/test/turbocoder_test.c b/srslte/lib/fec/test/turbocoder_test.c index 949cb986b..91700abdc 100644 --- a/srslte/lib/fec/test/turbocoder_test.c +++ b/srslte/lib/fec/test/turbocoder_test.c @@ -64,6 +64,7 @@ void parse_args(int argc, char **argv) { uint8_t input_bytes[6144/8]; uint8_t input_bits[6144]; uint8_t parity[3*6144+12]; +uint8_t parity_bits[3*6144+12]; uint8_t output_bits[3*6144+12]; uint8_t output_bits2[3*6144+12]; @@ -99,24 +100,23 @@ int main(int argc, char **argv) { } srslte_tcod_encode(&tcod, input_bits, output_bits, long_cb); - srslte_tcod_encode_lut(&tcod, input_bytes, parity, long_cb); + srslte_tcod_encode_lut(&tcod, input_bytes, parity, len); - if (SRSLTE_VERBOSE_ISINFO()) { - printf("1st encoder\n"); - srslte_vec_fprint_b(stdout, output_bits2, long_cb); - srslte_vec_fprint_b(stdout, output_bits, long_cb); - - printf("2nd encoder\n"); - srslte_vec_fprint_b(stdout, &output_bits2[long_cb], long_cb); - srslte_vec_fprint_b(stdout, &output_bits[long_cb], long_cb); + srslte_bit_unpack_vector(parity, parity_bits, 2*(long_cb+4)); + + for (int i=0;imod[i], modulations[i], true)) { goto clean; } + srslte_modem_table_bytes(&q->mod[i]); } srslte_sch_init(&q->dl_sch); @@ -509,14 +510,14 @@ int srslte_pdsch_encode_rnti(srslte_pdsch_t *q, if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) { return SRSLTE_ERROR; } - srslte_scrambling_b_offset(&seq, (uint8_t*) q->e, 0, cfg->nbits.nof_bits); + srslte_scrambling_bytes_offset(&seq, (uint8_t*) q->e, 0, cfg->nbits.nof_bits); srslte_sequence_free(&seq); } else { - srslte_scrambling_b_offset(&q->seq[cfg->sf_idx], (uint8_t*) q->e, 0, cfg->nbits.nof_bits); + srslte_scrambling_bytes_offset(&q->seq[cfg->sf_idx], (uint8_t*) q->e, 0, cfg->nbits.nof_bits); } - srslte_mod_modulate(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->e, q->d, cfg->nbits.nof_bits); - + srslte_mod_modulate_bytes(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->e, q->d, cfg->nbits.nof_bits); + /* TODO: only diversity supported */ if (q->cell.nof_ports > 1) { srslte_layermap_diversity(q->d, x, q->cell.nof_ports, cfg->nbits.nof_re); diff --git a/srslte/lib/phch/src/sch.c b/srslte/lib/phch/src/sch.c index 404786a01..731d06337 100644 --- a/srslte/lib/phch/src/sch.c +++ b/srslte/lib/phch/src/sch.c @@ -109,13 +109,13 @@ int srslte_sch_init(srslte_sch_t *q) { srslte_rm_turbo_gentables(); // Allocate floats for reception (LLRs) - q->cb_in = srslte_vec_malloc(sizeof(uint8_t) * SRSLTE_TCOD_MAX_LEN_CB+4); + q->cb_in = srslte_vec_malloc(sizeof(uint8_t) * (SRSLTE_TCOD_MAX_LEN_CB+8)/8); if (!q->cb_in) { goto clean; } - q->cb_out = srslte_vec_malloc(sizeof(float) * (3 * SRSLTE_TCOD_MAX_LEN_CB + 12)); - if (!q->cb_out) { + q->parity_bits = srslte_vec_malloc(sizeof(uint8_t) * (3 * SRSLTE_TCOD_MAX_LEN_CB + 16) / 8); + if (!q->parity_bits) { goto clean; } q->temp_g_bits = srslte_vec_malloc(sizeof(uint8_t)*SRSLTE_MAX_PRB*12*12*12); @@ -144,8 +144,8 @@ void srslte_sch_free(srslte_sch_t *q) { if (q->cb_in) { free(q->cb_in); } - if (q->cb_out) { - free(q->cb_out); + if (q->parity_bits) { + free(q->parity_bits); } if (q->temp_g_bits) { free(q->temp_g_bits); @@ -173,7 +173,7 @@ uint32_t srslte_sch_last_noi(srslte_sch_t *q) { * */ static int encode_tb_off(srslte_sch_t *q, - srslte_softbuffer_tx_t *soft_buffer, srslte_cbsegm_t *cb_segm, + srslte_softbuffer_tx_t *softbuffer, srslte_cbsegm_t *cb_segm, uint32_t Qm, uint32_t rv, uint32_t nof_e_bits, uint8_t *data, uint8_t *e_bits, uint32_t w_offset) { @@ -186,14 +186,19 @@ static int encode_tb_off(srslte_sch_t *q, if (q != NULL && e_bits != NULL && cb_segm != NULL && - soft_buffer != NULL) + softbuffer != NULL) { if (cb_segm->F) { fprintf(stderr, "Error filler bits are not supported. Use standard TBS\n"); return SRSLTE_ERROR; } - + + if (cb_segm->C > softbuffer->max_cb) { + fprintf(stderr, "Error number of CB (%d) exceeds soft buffer size (%d CBs)\n", cb_segm->C, softbuffer->max_cb); + return -1; + } + uint32_t Gp = nof_e_bits / Qm; uint32_t gamma = Gp; @@ -223,11 +228,14 @@ static int encode_tb_off(srslte_sch_t *q, rp = 0; for (i = 0; i < cb_segm->C; i++) { + uint32_t cblen_idx; /* Get read lengths */ if (i < cb_segm->C2) { cb_len = cb_segm->K2; + cblen_idx = cb_segm->K2_idx; } else { cb_len = cb_segm->K1; + cblen_idx = cb_segm->K1_idx; } if (cb_segm->C > 1) { rlen = cb_len - 24; @@ -243,13 +251,6 @@ static int encode_tb_off(srslte_sch_t *q, INFO("CB#%d: cb_len: %d, rlen: %d, wp: %d, rp: %d, E: %d\n", i, cb_len, rlen, wp, rp, n_e); - int ret = srslte_cbsegm_cbindex(cb_len); - if (ret < 0) { - fprintf(stderr, "Error invalid CBLEN=%d\n", cb_len); - return -1; - } - uint8_t cblen_idx = (uint8_t) ret; - if (data) { /* Copy data to another buffer, making space for the Codeblock CRC */ @@ -276,26 +277,23 @@ static int encode_tb_off(srslte_sch_t *q, } /* Turbo Encoding */ - srslte_tcod_encode_lut(&q->encoder, q->cb_in, (uint8_t*) q->cb_out, cblen_idx); + srslte_tcod_encode_lut(&q->encoder, q->cb_in, q->parity_bits, cblen_idx); if (SRSLTE_VERBOSE_ISDEBUG()) { DEBUG("CB#%d encoded: ", i); - srslte_vec_fprint_byte(stdout, q->cb_out, 2*cb_len/8); + srslte_vec_fprint_byte(stdout, q->parity_bits, 2*cb_len/8); } } DEBUG("RM cblen_idx=%d, n_e=%d, wp=%d, nof_e_bits=%d\n",cblen_idx, n_e, wp, nof_e_bits); /* Rate matching */ - if (3*cb_len+12 < soft_buffer->buff_size) { - if (srslte_rm_turbo_tx_lut(soft_buffer->buffer_b[i], q->cb_in, (uint8_t*) q->cb_out, &e_bits[(wp+w_offset)/8], cblen_idx, n_e, (wp+w_offset)%8, rv)) - { - fprintf(stderr, "Error in rate matching\n"); - return SRSLTE_ERROR; - } - } else { - fprintf(stderr, "Encoded CB length exceeds RM buffer (%d>%d)\n",3*cb_len+12,soft_buffer->buff_size); - return SRSLTE_ERROR; + if (srslte_rm_turbo_tx_lut(softbuffer->buffer_b[i], q->cb_in, q->parity_bits, + &e_bits[(wp+w_offset)/8], cblen_idx, n_e, (wp+w_offset)%8, rv)) + { + fprintf(stderr, "Error in rate matching\n"); + return SRSLTE_ERROR; } + /* Set read/write pointers */ rp += rlen; wp += n_e; @@ -347,6 +345,16 @@ static int decode_tb(srslte_sch_t *q, uint32_t Gp = nof_e_bits / Qm; uint32_t gamma=Gp; + if (cb_segm->F) { + fprintf(stderr, "Error filler bits are not supported. Use standard TBS\n"); + return SRSLTE_ERROR; + } + + if (cb_segm->C > softbuffer->max_cb) { + fprintf(stderr, "Error number of CB (%d) exceeds soft buffer size (%d CBs)\n", cb_segm->C, softbuffer->max_cb); + return -1; + } + if (cb_segm->C>0) { gamma = Gp%cb_segm->C; } @@ -355,11 +363,15 @@ static int decode_tb(srslte_sch_t *q, for (i = 0; i < cb_segm->C && early_stop; i++) { /* Get read/write lengths */ + uint32_t cblen_idx; if (i < cb_segm->C2) { cb_len = cb_segm->K2; + cblen_idx = cb_segm->K2_idx; } else { cb_len = cb_segm->K1; + cblen_idx = cb_segm->K1_idx; } + if (cb_segm->C == 1) { rlen = cb_len; } else { @@ -381,16 +393,14 @@ static int decode_tb(srslte_sch_t *q, cb_len, rlen - F, wp, rp, F, n_e); /* Rate Unmatching */ - if (srslte_rm_turbo_rx(softbuffer->buffer_f[i], softbuffer->buff_size, - &e_bits[rp], n_e, - (float*) q->cb_out, 3 * cb_len + 12, rv, F)) { + if (srslte_rm_turbo_rx_lut(&e_bits[rp], softbuffer->buffer_f[i], n_e, cblen_idx, rv)) { fprintf(stderr, "Error in rate matching\n"); return SRSLTE_ERROR; } if (SRSLTE_VERBOSE_ISDEBUG()) { DEBUG("CB#%d RMOUT: ", i); - srslte_vec_fprint_f(stdout, q->cb_out, 3*cb_len+12); + srslte_vec_fprint_f(stdout, softbuffer->buffer_f[i], 3*cb_len+12); } /* Turbo Decoding with CRC-based early stopping */ @@ -403,7 +413,7 @@ static int decode_tb(srslte_sch_t *q, srslte_tdec_reset(&q->decoder, cb_len); do { - srslte_tdec_iteration(&q->decoder, (float*) q->cb_out, cb_len); + srslte_tdec_iteration(&q->decoder, softbuffer->buffer_f[i], cb_len); q->nof_iterations++; if (cb_segm->C > 1) { diff --git a/srslte/lib/phch/test/CMakeLists.txt b/srslte/lib/phch/test/CMakeLists.txt index 6a29a1231..09039c262 100644 --- a/srslte/lib/phch/test/CMakeLists.txt +++ b/srslte/lib/phch/test/CMakeLists.txt @@ -94,9 +94,9 @@ ADD_EXECUTABLE(pdsch_test pdsch_test.c) TARGET_LINK_LIBRARIES(pdsch_test srslte) ADD_TEST(pdsch_test_bpsk pdsch_test -l 504 -m 1 -n 50 -r 2) -ADD_TEST(pdsch_test_qpsk pdsch_test -l 1000 -m 2 -n 50 -r 1) -ADD_TEST(pdsch_test_qam16 pdsch_test -l 50000 -m 4 -n 100) -ADD_TEST(pdsch_test_qam64 pdsch_test -l 61664 -m 6 -n 100 -r 0) +ADD_TEST(pdsch_test_qpsk pdsch_test -l 2216 -m 2 -n 50 -r 1) +ADD_TEST(pdsch_test_qam16 pdsch_test -l 18336 -m 4 -n 100) +ADD_TEST(pdsch_test_qam64 pdsch_test -l 75376 -m 6 -n 100 -r 0) BuildMex(MEXNAME pdsch SOURCES pdsch_test_mex.c LIBRARIES srslte srslte_mex) BuildMex(MEXNAME dlsch_encode SOURCES dlsch_encode_test_mex.c LIBRARIES srslte srslte_mex) diff --git a/srslte/lib/phch/test/pdsch_test.c b/srslte/lib/phch/test/pdsch_test.c index ccc9b42d5..ed3b7ea2c 100644 --- a/srslte/lib/phch/test/pdsch_test.c +++ b/srslte/lib/phch/test/pdsch_test.c @@ -37,6 +37,7 @@ srslte_cell_t cell = { 6, // nof_prb 1, // nof_ports + 0, 0, // cell_id SRSLTE_CP_NORM, // cyclic prefix SRSLTE_PHICH_SRSLTE_PHICH_R_1_6, // PHICH resources @@ -220,7 +221,7 @@ int main(int argc, char **argv) { ce[i][j] = 1; } } - + gettimeofday(&t[1], NULL); int r = srslte_pdsch_decode(&pdsch, &pdsch_cfg, &softbuffer_rx, slot_symbols[0], ce, 0, data); gettimeofday(&t[2], NULL);