From 50ec3a161ecc59aa8a1cad51b09e6ea3b798100a Mon Sep 17 00:00:00 2001 From: ismagom Date: Mon, 21 Sep 2015 13:51:28 +0200 Subject: [PATCH] New algorithm for QPSK demodulation. Added Turbodecoder precomputation of permutation tables. Added LUT for DCI size calculation. Using Volk for descrambling. --- cmake/modules/FindVolk.cmake | 2 + matlab/tests/pdcch_bler.m | 1 + matlab/tests/pusch_test.m | 2 +- srslte/include/srslte/common/sequence.h | 1 + srslte/include/srslte/fec/turbocoder.h | 1 - srslte/include/srslte/fec/turbodecoder.h | 4 +- srslte/include/srslte/phch/dci.h | 5 +- srslte/include/srslte/utils/debug.h | 14 +-- srslte/include/srslte/utils/vector.h | 3 + srslte/lib/common/src/sequence.c | 13 +++ srslte/lib/fec/src/turbocoder.c | 13 +-- srslte/lib/fec/src/turbodecoder.c | 111 +++++++++++-------- srslte/lib/modem/src/demod_soft.c | 11 +- srslte/lib/modem/test/modem_test.c | 18 ++-- srslte/lib/phch/src/dci.c | 36 ++++--- srslte/lib/phch/src/dci_sz_table.h | 132 +++++++++++++++++++++++ srslte/lib/phch/src/pdcch.c | 7 +- srslte/lib/phch/src/pusch.c | 4 +- srslte/lib/phch/test/pdcch_test.c | 28 ++++- srslte/lib/scrambling/src/scrambling.c | 12 +-- srslte/lib/utils/src/vector.c | 11 ++ 21 files changed, 322 insertions(+), 107 deletions(-) create mode 100644 srslte/lib/phch/src/dci_sz_table.h diff --git a/cmake/modules/FindVolk.cmake b/cmake/modules/FindVolk.cmake index 47ea99e4a..3c70329e6 100644 --- a/cmake/modules/FindVolk.cmake +++ b/cmake/modules/FindVolk.cmake @@ -34,6 +34,7 @@ CHECK_FUNCTION_EXISTS_MATH(volk_32fc_x2_multiply_32fc HAVE_VOLK_MULT2_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32fc_x2_multiply_conjugate_32fc HAVE_VOLK_MULT2_CONJ_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32fc_32f_multiply_32fc HAVE_VOLK_MULT_REAL_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32f_s32f_multiply_32f HAVE_VOLK_MULT_FLOAT_FUNCTION) +CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_multiply_32f HAVE_VOLK_MULT_REAL2_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32fc_magnitude_32f HAVE_VOLK_MAG_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_divide_32f HAVE_VOLK_DIVIDE_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32fc_32f_dot_prod_32fc HAVE_VOLK_DOTPROD_FC_FUNCTION) @@ -78,6 +79,7 @@ IF(VOLK_FOUND) CHECK_FUNCTION_EXISTS_MATH(volk_32fc_x2_square_dist_32f HAVE_VOLK_SQUARE_DIST_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32fc_deinterleave_real_32f HAVE_VOLK_DEINTERLEAVE_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32fc_index_max_16u HAVE_VOLK_MAX_ABS_FUNCTION) + CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_multiply_32f HAVE_VOLK_MULT_REAL2_FUNCTION) diff --git a/matlab/tests/pdcch_bler.m b/matlab/tests/pdcch_bler.m index 2964100f3..7757373e2 100644 --- a/matlab/tests/pdcch_bler.m +++ b/matlab/tests/pdcch_bler.m @@ -1,3 +1,4 @@ + %% PDCCH Blind Search and DCI Decoding + PCFICH encoding/decoding %% Cell-Wide Settings diff --git a/matlab/tests/pusch_test.m b/matlab/tests/pusch_test.m index fdcd3a76d..ed74ae8e6 100644 --- a/matlab/tests/pusch_test.m +++ b/matlab/tests/pusch_test.m @@ -14,7 +14,7 @@ for p=1:ueConfig.NULRB for bri=1:length(betas) for back=1:length(betas) for c=1:length(cqilen) - for s=0 + for s=0:9 ueConfig.NSubframe=s; puschConfig.PRBSet=(0:p-1)'; diff --git a/srslte/include/srslte/common/sequence.h b/srslte/include/srslte/common/sequence.h index 6d33a7d3c..729a5a8a6 100644 --- a/srslte/include/srslte/common/sequence.h +++ b/srslte/include/srslte/common/sequence.h @@ -43,6 +43,7 @@ typedef struct SRSLTE_API { uint8_t *c; uint8_t *c_bytes; + float *c_float; uint32_t len; } srslte_sequence_t; diff --git a/srslte/include/srslte/fec/turbocoder.h b/srslte/include/srslte/fec/turbocoder.h index da70a1e32..51186b727 100644 --- a/srslte/include/srslte/fec/turbocoder.h +++ b/srslte/include/srslte/fec/turbocoder.h @@ -51,7 +51,6 @@ typedef struct SRSLTE_API { uint32_t max_long_cb; uint8_t *temp; - srslte_tc_interl_t interl; } srslte_tcod_t; diff --git a/srslte/include/srslte/fec/turbodecoder.h b/srslte/include/srslte/fec/turbodecoder.h index 89581ba38..14ec74915 100644 --- a/srslte/include/srslte/fec/turbodecoder.h +++ b/srslte/include/srslte/fec/turbodecoder.h @@ -42,6 +42,7 @@ #include "srslte/config.h" #include "srslte/fec/tc_interl.h" +#include "srslte/fec/cbsegm.h" #define SRSLTE_TCOD_RATE 3 #define SRSLTE_TCOD_TOTALTAIL 12 @@ -67,7 +68,8 @@ typedef struct SRSLTE_API { srslte_llr_t *syst; srslte_llr_t *parity; - srslte_tc_interl_t interleaver; + int current_cbidx; + srslte_tc_interl_t interleaver[SRSLTE_NOF_TC_CB_SIZES]; } srslte_tdec_t; SRSLTE_API int srslte_tdec_init(srslte_tdec_t * h, diff --git a/srslte/include/srslte/phch/dci.h b/srslte/include/srslte/phch/dci.h index 43821cfb5..a666369ba 100644 --- a/srslte/include/srslte/phch/dci.h +++ b/srslte/include/srslte/phch/dci.h @@ -49,7 +49,7 @@ #define SRSLTE_RAR_GRANT_LEN 20 typedef enum { - SRSLTE_DCI_FORMAT0, + SRSLTE_DCI_FORMAT0 = 0, SRSLTE_DCI_FORMAT1, SRSLTE_DCI_FORMAT1A, SRSLTE_DCI_FORMAT1C, @@ -161,4 +161,7 @@ SRSLTE_API int srslte_dci_msg_unpack_pdsch(srslte_dci_msg_t *msg, SRSLTE_API uint32_t srslte_dci_format_sizeof(srslte_dci_format_t format, uint32_t nof_prb); +SRSLTE_API uint32_t srslte_dci_format_sizeof_lut(srslte_dci_format_t format, + uint32_t nof_prb); + #endif // DCI_ diff --git a/srslte/include/srslte/utils/debug.h b/srslte/include/srslte/utils/debug.h index 2e781c9b5..424bb0ccb 100644 --- a/srslte/include/srslte/utils/debug.h +++ b/srslte/include/srslte/utils/debug.h @@ -39,14 +39,14 @@ #include #include "srslte/config.h" -#define SRSLTE_VERBOSE_DEBUG 2 +#define SRSLTE_VERBOSE_DEBUG 2 #define SRSLTE_VERBOSE_INFO 1 #define SRSLTE_VERBOSE_NONE 0 #include SRSLTE_API void get_time_interval(struct timeval * tdata); -#ifndef SRSLTE_DEBUG_DISABLED +#define SRSLTE_DEBUG_ENABLED 0 SRSLTE_API extern int srslte_verbose; @@ -58,17 +58,11 @@ SRSLTE_API extern int srslte_verbose; #define PRINT_INFO srslte_verbose=SRSLTE_VERBOSE_INFO #define PRINT_NONE srslte_verbose=SRSLTE_VERBOSE_NONE -#define DEBUG(_fmt, ...) if (srslte_verbose >= SRSLTE_VERBOSE_DEBUG) \ +#define DEBUG(_fmt, ...) if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG) \ fprintf(stdout, "[DEBUG]: " _fmt, __VA_ARGS__) -#define INFO(_fmt, ...) if (srslte_verbose >= SRSLTE_VERBOSE_INFO) \ +#define INFO(_fmt, ...) if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO) \ fprintf(stdout, "[INFO]: " _fmt, __VA_ARGS__) -#else // SRSLTE_DEBUG_DISABLED - -#define DEBUG -#define INFO - -#endif // SRSLTE_DEBUG_DISABLED #endif // DEBUG_H diff --git a/srslte/include/srslte/utils/vector.h b/srslte/include/srslte/utils/vector.h index b09c4c6ee..81cb66bb6 100644 --- a/srslte/include/srslte/utils/vector.h +++ b/srslte/include/srslte/utils/vector.h @@ -119,6 +119,9 @@ SRSLTE_API void srslte_vec_prod_cfc(cf_t *x, float *y, cf_t *z, uint32_t len); /* conjugate vector product (element-wise) */ SRSLTE_API void srslte_vec_prod_conj_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len); +/* real vector product (element-wise) */ +SRSLTE_API void srslte_vec_prod_fff(float *x, float *y, float *z, uint32_t len); + /* Dot-product */ SRSLTE_API cf_t srslte_vec_dot_prod_cfc(cf_t *x, float *y, uint32_t len); SRSLTE_API cf_t srslte_vec_dot_prod_ccc(cf_t *x, cf_t *y, uint32_t len); diff --git a/srslte/lib/common/src/sequence.c b/srslte/lib/common/src/sequence.c index 109c036c0..0fb6feba1 100644 --- a/srslte/lib/common/src/sequence.c +++ b/srslte/lib/common/src/sequence.c @@ -83,6 +83,9 @@ int srslte_sequence_LTE_pr(srslte_sequence_t *q, uint32_t len, uint32_t seed) { q->len = len; srslte_sequence_set_LTE_pr(q, seed); srslte_bit_pack_vector(q->c, q->c_bytes, len); + for (int i=0;ic_float[i] = (1-2*q->c[i]); + } return SRSLTE_SUCCESS; } @@ -92,6 +95,9 @@ int srslte_sequence_init(srslte_sequence_t *q, uint32_t len) { if (q->c_bytes) { free(q->c_bytes); } + if (q->c_float) { + free(q->c_float); + } } if (!q->c) { q->c = srslte_vec_malloc(len * sizeof(uint8_t)); @@ -102,6 +108,10 @@ int srslte_sequence_init(srslte_sequence_t *q, uint32_t len) { if (!q->c_bytes) { return SRSLTE_ERROR; } + q->c_float = srslte_vec_malloc(len * sizeof(float)); + if (!q->c_float) { + return SRSLTE_ERROR; + } q->len = len; } return SRSLTE_SUCCESS; @@ -114,6 +124,9 @@ void srslte_sequence_free(srslte_sequence_t *q) { if (q->c_bytes) { free(q->c_bytes); } + if (q->c_float) { + free(q->c_float); + } bzero(q, sizeof(srslte_sequence_t)); } diff --git a/srslte/lib/fec/src/turbocoder.c b/srslte/lib/fec/src/turbocoder.c index e060943d3..5456c6ad4 100644 --- a/srslte/lib/fec/src/turbocoder.c +++ b/srslte/lib/fec/src/turbocoder.c @@ -49,9 +49,6 @@ static bool table_initiated = false; int srslte_tcod_init(srslte_tcod_t *h, uint32_t max_long_cb) { - if (srslte_tc_interl_init(&h->interl, max_long_cb)) { - return -1; - } h->max_long_cb = max_long_cb; h->temp = srslte_vec_malloc(max_long_cb/8); @@ -63,7 +60,6 @@ int srslte_tcod_init(srslte_tcod_t *h, uint32_t max_long_cb) { } void srslte_tcod_free(srslte_tcod_t *h) { - srslte_tc_interl_free(&h->interl); h->max_long_cb = 0; if (h->temp) { free(h->temp); @@ -86,12 +82,13 @@ int srslte_tcod_encode(srslte_tcod_t *h, uint8_t *input, uint8_t *output, uint32 return -1; } - if (srslte_tc_interl_LTE_gen(&h->interl, long_cb)) { - fprintf(stderr, "Error initiating TC interleaver\n"); + int longcb_idx = srslte_cbsegm_cbindex(long_cb); + if (longcb_idx < 0) { + fprintf(stderr, "Invalid CB size %d\n", long_cb); return -1; } - - per = h->interl.forward; + + per = tcod_per_fw[longcb_idx]; reg1_0 = 0; reg1_1 = 0; diff --git a/srslte/lib/fec/src/turbodecoder.c b/srslte/lib/fec/src/turbodecoder.c index 57a4455bd..c702df6e9 100644 --- a/srslte/lib/fec/src/turbodecoder.c +++ b/srslte/lib/fec/src/turbodecoder.c @@ -239,10 +239,13 @@ int srslte_tdec_init(srslte_tdec_t * h, uint32_t max_long_cb) goto clean_and_exit; } - if (srslte_tc_interl_init(&h->interleaver, h->max_long_cb) < 0) { - goto clean_and_exit; + for (int i=0;iinterleaver[i], srslte_cbsegm_cbsize(i)) < 0) { + goto clean_and_exit; + } + srslte_tc_interl_LTE_gen(&h->interleaver[i], srslte_cbsegm_cbsize(i)); } - + h->current_cbidx = -1; ret = 0; clean_and_exit:if (ret == -1) { srslte_tdec_free(h); @@ -270,7 +273,9 @@ void srslte_tdec_free(srslte_tdec_t * h) srslte_map_gen_free(&h->dec); - srslte_tc_interl_free(&h->interleaver); + for (int i=0;iinterleaver[i]); + } bzero(h, sizeof(srslte_tdec_t)); } @@ -279,40 +284,47 @@ void srslte_tdec_iteration(srslte_tdec_t * h, srslte_llr_t * input, uint32_t lon { uint32_t i; - // Prepare systematic and parity bits for MAP DEC #1 - for (i = 0; i < long_cb; i++) { - h->syst[i] = input[SRSLTE_TCOD_RATE * i] + h->w[i]; - h->parity[i] = input[SRSLTE_TCOD_RATE * i + 1]; - } - for (i = long_cb; i < long_cb + SRSLTE_TCOD_RATE; i++) { - h->syst[i] = input[SRSLTE_TCOD_RATE * long_cb + NINPUTS * (i - long_cb)]; - h->parity[i] = input[SRSLTE_TCOD_RATE * long_cb + NINPUTS * (i - long_cb) + 1]; - } + if (h->current_cbidx >= 0) { - // Run MAP DEC #1 - srslte_map_gen_dec(&h->dec, h->syst, h->parity, h->llr1, long_cb); + uint32_t *inter = h->interleaver[h->current_cbidx].forward; + uint32_t *deinter = h->interleaver[h->current_cbidx].reverse; + + // Prepare systematic and parity bits for MAP DEC #1 + for (i = 0; i < long_cb; i++) { + h->syst[i] = input[SRSLTE_TCOD_RATE * i] + h->w[i]; + h->parity[i] = input[SRSLTE_TCOD_RATE * i + 1]; + } + for (i = long_cb; i < long_cb + SRSLTE_TCOD_RATE; i++) { + h->syst[i] = input[SRSLTE_TCOD_RATE * long_cb + NINPUTS * (i - long_cb)]; + h->parity[i] = input[SRSLTE_TCOD_RATE * long_cb + NINPUTS * (i - long_cb) + 1]; + } - // Prepare systematic and parity bits for MAP DEC #1 - for (i = 0; i < long_cb; i++) { - h->syst[i] = h->llr1[h->interleaver.forward[i]] - - h->w[h->interleaver.forward[i]]; - h->parity[i] = input[SRSLTE_TCOD_RATE * i + 2]; - } - for (i = long_cb; i < long_cb + SRSLTE_TCOD_RATE; i++) { - h->syst[i] = - input[SRSLTE_TCOD_RATE * long_cb + NINPUTS * SRSLTE_TCOD_RATE + NINPUTS * (i - long_cb)]; - h->parity[i] = input[SRSLTE_TCOD_RATE * long_cb + NINPUTS * SRSLTE_TCOD_RATE - + NINPUTS * (i - long_cb) + 1]; - } + // Run MAP DEC #1 + srslte_map_gen_dec(&h->dec, h->syst, h->parity, h->llr1, long_cb); - // Run MAP DEC #1 - srslte_map_gen_dec(&h->dec, h->syst, h->parity, h->llr2, long_cb); - - // Update a-priori LLR from the last iteration - for (i = 0; i < long_cb; i++) { - h->w[i] += h->llr2[h->interleaver.reverse[i]] - h->llr1[i]; - } + // Prepare systematic and parity bits for MAP DEC #1 + for (i = 0; i < long_cb; i++) { + h->syst[i] = h->llr1[inter[i]] + - h->w[inter[i]]; + h->parity[i] = input[SRSLTE_TCOD_RATE * i + 2]; + } + for (i = long_cb; i < long_cb + SRSLTE_TCOD_RATE; i++) { + h->syst[i] = + input[SRSLTE_TCOD_RATE * long_cb + NINPUTS * SRSLTE_TCOD_RATE + NINPUTS * (i - long_cb)]; + h->parity[i] = input[SRSLTE_TCOD_RATE * long_cb + NINPUTS * SRSLTE_TCOD_RATE + + NINPUTS * (i - long_cb) + 1]; + } + // Run MAP DEC #1 + srslte_map_gen_dec(&h->dec, h->syst, h->parity, h->llr2, long_cb); + + // Update a-priori LLR from the last iteration + for (i = 0; i < long_cb; i++) { + h->w[i] += h->llr2[deinter[i]] - h->llr1[i]; + } + } else { + fprintf(stderr, "Error CB index not set (call srslte_tdec_reset() first\n"); + } } int srslte_tdec_reset(srslte_tdec_t * h, uint32_t long_cb) @@ -323,28 +335,41 @@ int srslte_tdec_reset(srslte_tdec_t * h, uint32_t long_cb) return -1; } memset(h->w, 0, sizeof(srslte_llr_t) * long_cb); - return srslte_tc_interl_LTE_gen(&h->interleaver, long_cb); + h->current_cbidx = srslte_cbsegm_cbindex(long_cb); + if (h->current_cbidx < 0) { + fprintf(stderr, "Invalid CB length %d\n", long_cb); + return -1; + } + return 0; } void srslte_tdec_decision(srslte_tdec_t * h, uint8_t *output, uint32_t long_cb) { + uint32_t *deinter = h->interleaver[h->current_cbidx].reverse; uint32_t i; for (i = 0; i < long_cb; i++) { - output[i] = (h->llr2[h->interleaver.reverse[i]] > 0) ? 1 : 0; + output[i] = (h->llr2[deinter[i]] > 0) ? 1 : 0; } } void srslte_tdec_decision_byte(srslte_tdec_t * h, uint8_t *output, uint32_t long_cb) { - uint32_t i, j; + uint32_t i; + uint8_t mask[8] = {0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1}; + uint32_t *deinter = h->interleaver[h->current_cbidx].reverse; + // long_cb is always byte aligned for (i = 0; i < long_cb/8; i++) { - output[i] = 0; - for (j=0;j<8;j++) { - if (h->llr2[h->interleaver.reverse[8*i+j]] > 0) { - output[i] |= 1<<(7-j); - } - } + uint8_t out0 = h->llr2[deinter[8*i+0]]>0?mask[0]:0; + uint8_t out1 = h->llr2[deinter[8*i+1]]>0?mask[1]:0; + uint8_t out2 = h->llr2[deinter[8*i+2]]>0?mask[2]:0; + uint8_t out3 = h->llr2[deinter[8*i+3]]>0?mask[3]:0; + uint8_t out4 = h->llr2[deinter[8*i+4]]>0?mask[4]:0; + uint8_t out5 = h->llr2[deinter[8*i+5]]>0?mask[5]:0; + uint8_t out6 = h->llr2[deinter[8*i+6]]>0?mask[6]:0; + uint8_t out7 = h->llr2[deinter[8*i+7]]>0?mask[7]:0; + + output[i] = out0 | out1 | out2 | out3 | out4 | out5 | out6 | out7; } } diff --git a/srslte/lib/modem/src/demod_soft.c b/srslte/lib/modem/src/demod_soft.c index 6be766bc2..3d6906849 100644 --- a/srslte/lib/modem/src/demod_soft.c +++ b/srslte/lib/modem/src/demod_soft.c @@ -91,12 +91,19 @@ int srslte_demod_soft_demodulate(srslte_demod_soft_t *q, const cf_t* symbols, fl break; case SRSLTE_DEMOD_SOFT_ALG_APPROX: if (nsymbols <= q->max_symbols) { - llr_approx(symbols, llr, nsymbols, q->table->nsymbols, + + switch(q->table->nbits_x_symbol) { + case 2: + srslte_vec_sc_prod_fff((float*) symbols, -sqrt(2)/q->sigma, llr, nsymbols*2); + break; + default: + llr_approx(symbols, llr, nsymbols, q->table->nsymbols, q->table->nbits_x_symbol, q->table->symbol_table, q->table->soft_table.idx, q->table->soft_table.d_idx, q->table->soft_table.min_idx, q->sigma, q->zones, q->dd); - + break; + } } else { fprintf(stderr, "Too many symbols (%d>%d)\n", nsymbols, q->max_symbols); return -1; diff --git a/srslte/lib/modem/test/modem_test.c b/srslte/lib/modem/test/modem_test.c index 1b9a24d6e..2b948a9e8 100644 --- a/srslte/lib/modem/test/modem_test.c +++ b/srslte/lib/modem/test/modem_test.c @@ -40,14 +40,14 @@ time_t start, finish; struct timeval x, y; int num_bits = 1000; -srslte_mod_t modulation; -bool soft_output = false, soft_exact = false; +srslte_mod_t modulation = SRSLTE_MOD_BPSK; +bool soft_output = true, soft_exact = false; void usage(char *prog) { printf("Usage: %s [nmse]\n", prog); printf("\t-n num_bits [Default %d]\n", num_bits); printf("\t-m modulation (1: BPSK, 2: QPSK, 3: QAM16, 4: QAM64) [Default BPSK]\n"); - printf("\t-s soft outputs [Default hard]\n"); + printf("\t-s soft outputs [Default %s]\n", soft_output?"soft":"hard"); printf("\t-e soft outputs exact algorithm [Default approx]\n"); } @@ -99,12 +99,8 @@ int main(int argc, char **argv) { srslte_demod_soft_t demod_soft; uint8_t *input, *input_bytes, *output; cf_t *symbols, *symbols_bytes; - float *llr; + float *llr, *llr2; -// unsigned long strt, fin; -// strt = x->tv_usec; -// fin = y->tv_usec; - parse_args(argc, argv); /* initialize objects */ @@ -163,6 +159,12 @@ int main(int argc, char **argv) { exit(-1); } + llr2 = srslte_vec_malloc(sizeof(float) * num_bits); + if (!llr2) { + perror("malloc"); + exit(-1); + } + /* generate random data */ for (i=0;icqi_request; // Padding with zeros - uint32_t n = dci_format0_sizeof(nof_prb); + uint32_t n = srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT0, nof_prb); while (y - msg->data < n) { *y++ = 0; } @@ -380,7 +388,7 @@ int dci_format0_unpack(srslte_dci_msg_t *msg, srslte_ra_ul_dci_t *data, uint32_t uint32_t n_ul_hop; /* Make sure it's a SRSLTE_DCI_FORMAT0 message */ - if (msg->nof_bits != srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT0, nof_prb)) { + if (msg->nof_bits != srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT0, nof_prb)) { fprintf(stderr, "Invalid message length for format 0\n"); return SRSLTE_ERROR; } @@ -474,7 +482,7 @@ int dci_format1_pack(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, uint32_t n *y++ = 0; // Padding with zeros - uint32_t n = dci_format1_sizeof(nof_prb); + uint32_t n = srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1, nof_prb); while (y - msg->data < n) { *y++ = 0; } @@ -489,7 +497,7 @@ int dci_format1_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_t uint8_t *y = msg->data; /* Make sure it's a SRSLTE_DCI_FORMAT1 message */ - if (msg->nof_bits != srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1, nof_prb)) { + if (msg->nof_bits != srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1, nof_prb)) { fprintf(stderr, "Invalid message length for format 1\n"); return SRSLTE_ERROR; } @@ -614,7 +622,7 @@ int dci_format1As_pack(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, uint32_t } // Padding with zeros - uint32_t n = dci_format1A_sizeof(nof_prb); + uint32_t n = srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1A, nof_prb); while (y - msg->data < n) { *y++ = 0; } @@ -633,7 +641,7 @@ int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 uint8_t *y = msg->data; /* Make sure it's a SRSLTE_DCI_FORMAT0 message */ - if (msg->nof_bits != srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1A, nof_prb)) { + if (msg->nof_bits != srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1A, nof_prb)) { fprintf(stderr, "Invalid message length for format 1A\n"); return SRSLTE_ERROR; } @@ -757,7 +765,7 @@ int dci_format1Cs_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 /* pack bits */ uint8_t *y = msg->data; - if (msg->nof_bits != srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1C, nof_prb)) { + if (msg->nof_bits != srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1C, nof_prb)) { fprintf(stderr, "Invalid message length for format 1C\n"); return SRSLTE_ERROR; } @@ -804,11 +812,11 @@ int srslte_dci_msg_pack_pdsch(srslte_ra_dl_dci_t *data, srslte_dci_msg_t *msg, s int srslte_dci_msg_unpack_pdsch(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32_t nof_prb, bool crc_is_crnti) { - if (msg->nof_bits == srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1, nof_prb)) { + if (msg->nof_bits == srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1, nof_prb)) { return dci_format1_unpack(msg, data, nof_prb); - } else if (msg->nof_bits == srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1A, nof_prb)) { + } else if (msg->nof_bits == srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1A, nof_prb)) { return dci_format1As_unpack(msg, data, nof_prb, crc_is_crnti); - } else if (msg->nof_bits == srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1C, nof_prb)) { + } else if (msg->nof_bits == srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1C, nof_prb)) { return dci_format1Cs_unpack(msg, data, nof_prb); } else { return SRSLTE_ERROR; @@ -877,16 +885,16 @@ int srslte_dci_msg_get_type(srslte_dci_msg_t *msg, srslte_dci_msg_type_t *type, uint16_t msg_rnti) { DEBUG("Get message type: nof_bits=%d, msg_rnti=0x%x\n", msg->nof_bits, msg_rnti); - if (msg->nof_bits == srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT0, nof_prb) + if (msg->nof_bits == srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT0, nof_prb) && !msg->data[0]) { type->type = SRSLTE_DCI_MSG_TYPE_PUSCH_SCHED; type->format = SRSLTE_DCI_FORMAT0; return SRSLTE_SUCCESS; - } else if (msg->nof_bits == srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1, nof_prb)) { + } else if (msg->nof_bits == srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1, nof_prb)) { type->type = SRSLTE_DCI_MSG_TYPE_PDSCH_SCHED; // only these 2 types supported type->format = SRSLTE_DCI_FORMAT1; return SRSLTE_SUCCESS; - } else if (msg->nof_bits == srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1A, nof_prb)) { + } else if (msg->nof_bits == srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1A, nof_prb)) { /* The RNTI is not the only condition. Also some fields in the packet. * if (msg_rnti >= SRSLTE_CRNTI_START && msg_rnti <= SRSLTE_CRNTI_END) { type->type = SRSLTE_DCI_MSG_TYPE_RA_PROC_PDCCH; @@ -897,7 +905,7 @@ int srslte_dci_msg_get_type(srslte_dci_msg_t *msg, srslte_dci_msg_type_t *type, type->format = SRSLTE_DCI_FORMAT1A; //} return SRSLTE_SUCCESS; - } else if (msg->nof_bits == srslte_dci_format_sizeof(SRSLTE_DCI_FORMAT1C, nof_prb)) { + } else if (msg->nof_bits == srslte_dci_format_sizeof_lut(SRSLTE_DCI_FORMAT1C, nof_prb)) { if (msg_rnti == SRSLTE_MRNTI) { type->type = SRSLTE_DCI_MSG_TYPE_MCCH_CHANGE; type->format = SRSLTE_DCI_FORMAT1C; diff --git a/srslte/lib/phch/src/dci_sz_table.h b/srslte/lib/phch/src/dci_sz_table.h new file mode 100644 index 000000000..e104e11e6 --- /dev/null +++ b/srslte/lib/phch/src/dci_sz_table.h @@ -0,0 +1,132 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 The srsLTE Developers. See the + * COPYRIGHT file at the top-level directory of this distribution. + * + * \section LICENSE + * + * This file is part of the srsLTE library. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + + + +static uint32_t dci_sz_table[100][4] = { + {15, 13, 15, 5}, + {15, 17, 15, 5}, + {17, 15, 17, 5}, + {18, 17, 18, 5}, + {19, 17, 19, 7}, + {19, 18, 19, 7}, + {21, 19, 21, 8}, + {21, 22, 21, 8}, + {21, 22, 21, 9}, + {21, 22, 21, 9}, + {21, 23, 21, 9}, + {22, 21, 22, 9}, + {22, 21, 22, 9}, + {22, 21, 22, 9}, + {22, 21, 22, 10}, + {22, 23, 22, 10}, + {23, 22, 23, 11}, + {23, 25, 23, 11}, + {23, 25, 23, 11}, + {23, 25, 23, 11}, + {23, 25, 23, 11}, + {23, 25, 23, 11}, + {23, 25, 23, 11}, + {25, 27, 25, 12}, + {25, 27, 25, 12}, + {25, 27, 25, 12}, + {25, 27, 25, 12}, + {25, 23, 25, 11}, + {25, 27, 25, 11}, + {25, 27, 25, 12}, + {25, 27, 25, 12}, + {25, 27, 25, 12}, + {25, 27, 25, 12}, + {25, 27, 25, 12}, + {25, 27, 25, 13}, + {25, 27, 25, 13}, + {25, 27, 25, 13}, + {25, 27, 25, 13}, + {25, 27, 25, 13}, + {25, 27, 25, 13}, + {25, 28, 25, 13}, + {25, 28, 25, 13}, + {25, 28, 25, 13}, + {25, 29, 25, 13}, + {25, 29, 25, 13}, + {27, 29, 27, 13}, + {27, 30, 27, 13}, + {27, 30, 27, 13}, + {27, 30, 27, 13}, + {27, 31, 27, 13}, + {27, 31, 27, 13}, + {27, 31, 27, 13}, + {27, 33, 27, 13}, + {27, 33, 27, 13}, + {27, 33, 27, 13}, + {27, 33, 27, 13}, + {27, 33, 27, 13}, + {27, 33, 27, 13}, + {27, 34, 27, 13}, + {27, 34, 27, 13}, + {27, 34, 27, 13}, + {27, 35, 27, 13}, + {27, 35, 27, 13}, + {27, 35, 27, 13}, + {27, 30, 27, 14}, + {27, 31, 27, 14}, + {27, 31, 27, 14}, + {27, 31, 27, 14}, + {27, 31, 27, 14}, + {27, 33, 27, 14}, + {27, 33, 27, 14}, + {27, 33, 27, 14}, + {27, 33, 27, 14}, + {27, 33, 27, 14}, + {27, 33, 27, 14}, + {27, 33, 27, 14}, + {27, 33, 27, 14}, + {27, 34, 27, 14}, + {27, 34, 27, 14}, + {27, 34, 27, 14}, + {27, 34, 27, 14}, + {27, 35, 27, 14}, + {27, 35, 27, 14}, + {27, 35, 27, 14}, + {27, 35, 27, 14}, + {27, 36, 27, 14}, + {27, 36, 27, 14}, + {27, 36, 27, 14}, + {27, 36, 27, 14}, + {27, 37, 27, 14}, + {27, 37, 27, 14}, + {28, 37, 28, 14}, + {28, 37, 28, 14}, + {28, 38, 28, 14}, + {28, 38, 28, 15}, + {28, 38, 28, 15}, + {28, 38, 28, 15}, + {28, 39, 28, 15}, + {28, 39, 28, 15}, + {28, 39, 28, 15} +}; + diff --git a/srslte/lib/phch/src/pdcch.c b/srslte/lib/phch/src/pdcch.c index 01f7c2185..3b6f5ed11 100644 --- a/srslte/lib/phch/src/pdcch.c +++ b/srslte/lib/phch/src/pdcch.c @@ -333,7 +333,7 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t *q, fprintf(stderr, "Invalid location: nCCE: %d, L: %d, NofCCE: %d\n", location->ncce, location->L, q->nof_cce); } else { - uint32_t nof_bits = srslte_dci_format_sizeof(format, q->cell.nof_prb); + uint32_t nof_bits = srslte_dci_format_sizeof_lut(format, q->cell.nof_prb); uint32_t e_bits = PDCCH_FORMAT_NOF_BITS(location->L); DEBUG("Decoding DCI offset %d, e_bits: %d, msg_len %d (nCCE: %d, L: %d)\n", @@ -349,7 +349,7 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t *q, msg->data, e_bits, nof_bits, crc_rem); if (ret == SRSLTE_SUCCESS) { msg->nof_bits = nof_bits; - } + } } else { ret = SRSLTE_SUCCESS; } @@ -424,7 +424,8 @@ int srslte_pdcch_extract_llr(srslte_pdcch_t *q, cf_t *sf_symbols, cf_t *ce[SRSLT } /* demodulate symbols */ - srslte_demod_soft_sigma_set(&q->demod, 1.0); + //srslte_vec_sc_prod_fff((float*) q->d, -sqrt(2), q->llr, nof_symbols*2); + srslte_demod_soft_sigma_set(&q->demod, sqrt(0.5)); srslte_demod_soft_demodulate(&q->demod, q->d, q->llr, nof_symbols); /* descramble */ diff --git a/srslte/lib/phch/src/pusch.c b/srslte/lib/phch/src/pusch.c index ccbc3143b..4ef959691 100644 --- a/srslte/lib/phch/src/pusch.c +++ b/srslte/lib/phch/src/pusch.c @@ -502,8 +502,6 @@ int srslte_pusch_uci_encode(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srslte_s } } -uint8_t temp[1024*1024]; - /** Converts the PUSCH data bits to symbols mapped to the slot ready for transmission */ int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer, @@ -532,7 +530,7 @@ int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srs return SRSLTE_ERROR; } - if (rnti != q->rnti) { + if (rnti != q->rnti || !q->rnti_is_set) { srslte_sequence_t seq; if (srslte_sequence_pusch(&seq, rnti, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) { return SRSLTE_ERROR; diff --git a/srslte/lib/phch/test/pdcch_test.c b/srslte/lib/phch/test/pdcch_test.c index d7ae0a846..d89736c98 100644 --- a/srslte/lib/phch/test/pdcch_test.c +++ b/srslte/lib/phch/test/pdcch_test.c @@ -43,19 +43,21 @@ srslte_cell_t cell = { }; uint32_t cfi = 1; +bool print_dci_table; void usage(char *prog) { - printf("Usage: %s [cell.cpv]\n", prog); + printf("Usage: %s [cfpndv]\n", prog); printf("\t-c cell id [Default %d]\n", cell.id); printf("\t-f cfi [Default %d]\n", cfi); printf("\t-p cell.nof_ports [Default %d]\n", cell.nof_ports); printf("\t-n cell.nof_prb [Default %d]\n", cell.nof_prb); + printf("\t-d Print DCI table [Default %s]\n", print_dci_table?"yes":"no"); printf("\t-v [set srslte_verbose to debug, default none]\n"); } void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "cell.cpnfv")) != -1) { + while ((opt = getopt(argc, argv, "cfpndv")) != -1) { switch (opt) { case 'p': cell.nof_ports = atoi(argv[optind]); @@ -69,6 +71,9 @@ void parse_args(int argc, char **argv) { case 'c': cell.id = atoi(argv[optind]); break; + case 'd': + print_dci_table = true; + break; case 'v': srslte_verbose++; break; @@ -102,6 +107,25 @@ int test_dci_payload_size() { printf(" %2d:\t%2d\t%2d\t%2d\t%2d\n", n, x[0], x[1], x[2], x[3]); } printf("Ok\n"); + + if (print_dci_table) { + printf("dci_sz_table[100][4] = {\n"); + for (i=0;i<100;i++) { + printf(" {"); + for (int j=0;j<4;j++) { + printf("%d",srslte_dci_format_sizeof(formats[j], i)); + if (j<3) { + printf(", "); + } + } + if (i<99) { + printf("},\n"); + } else { + printf("}\n"); + } + } + printf("};\n"); + } return 0; } diff --git a/srslte/lib/scrambling/src/scrambling.c b/srslte/lib/scrambling/src/scrambling.c index 8aac5ef49..df010ec3a 100644 --- a/srslte/lib/scrambling/src/scrambling.c +++ b/srslte/lib/scrambling/src/scrambling.c @@ -37,12 +37,8 @@ void srslte_scrambling_f(srslte_sequence_t *s, float *data) { } void srslte_scrambling_f_offset(srslte_sequence_t *s, float *data, int offset, int len) { - int i; assert (len + offset <= s->len); - - for (i = 0; i < len; i++) { - data[i] = data[i] * (1-2*s->c[i + offset]); - } + srslte_vec_prod_fff(data, &s->c_float[offset], data, len); } void srslte_scrambling_c(srslte_sequence_t *s, cf_t *data) { @@ -50,12 +46,8 @@ void srslte_scrambling_c(srslte_sequence_t *s, cf_t *data) { } void srslte_scrambling_c_offset(srslte_sequence_t *s, cf_t *data, int offset, int len) { - int i; assert (len + offset <= s->len); - - for (i = 0; i < len; i++) { - data[i] = data[i] * (1 - 2 * s->c[i + offset]); - } + srslte_vec_prod_cfc(data, &s->c_float[offset], data, len); } void scrambling_b(uint8_t *c, uint8_t *data, int offset, int len) { diff --git a/srslte/lib/utils/src/vector.c b/srslte/lib/utils/src/vector.c index fd9ab4d12..57bfd0fb7 100644 --- a/srslte/lib/utils/src/vector.c +++ b/srslte/lib/utils/src/vector.c @@ -381,6 +381,17 @@ void srslte_vec_prod_cfc(cf_t *x, float *y, cf_t *z, uint32_t len) { #endif } +void srslte_vec_prod_fff(float *x, float *y, float *z, uint32_t len) { +#ifndef HAVE_VOLK_MULT_REAL2_FUNCTION + int i; + for (i=0;i