New algorithm for QPSK demodulation. Added Turbodecoder precomputation of permutation tables. Added LUT for DCI size calculation. Using Volk for descrambling.

master
ismagom 9 years ago
parent 06e537ca5b
commit 50ec3a161e

@ -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_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_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_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_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_32f_x2_divide_32f HAVE_VOLK_DIVIDE_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32fc_32f_dot_prod_32fc HAVE_VOLK_DOTPROD_FC_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_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_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_32fc_index_max_16u HAVE_VOLK_MAX_ABS_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_multiply_32f HAVE_VOLK_MULT_REAL2_FUNCTION)

@ -1,3 +1,4 @@
%% PDCCH Blind Search and DCI Decoding + PCFICH encoding/decoding %% PDCCH Blind Search and DCI Decoding + PCFICH encoding/decoding
%% Cell-Wide Settings %% Cell-Wide Settings

@ -14,7 +14,7 @@ for p=1:ueConfig.NULRB
for bri=1:length(betas) for bri=1:length(betas)
for back=1:length(betas) for back=1:length(betas)
for c=1:length(cqilen) for c=1:length(cqilen)
for s=0 for s=0:9
ueConfig.NSubframe=s; ueConfig.NSubframe=s;
puschConfig.PRBSet=(0:p-1)'; puschConfig.PRBSet=(0:p-1)';

@ -43,6 +43,7 @@
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
uint8_t *c; uint8_t *c;
uint8_t *c_bytes; uint8_t *c_bytes;
float *c_float;
uint32_t len; uint32_t len;
} srslte_sequence_t; } srslte_sequence_t;

@ -51,7 +51,6 @@
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
uint32_t max_long_cb; uint32_t max_long_cb;
uint8_t *temp; uint8_t *temp;
srslte_tc_interl_t interl;
} srslte_tcod_t; } srslte_tcod_t;

@ -42,6 +42,7 @@
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/fec/tc_interl.h" #include "srslte/fec/tc_interl.h"
#include "srslte/fec/cbsegm.h"
#define SRSLTE_TCOD_RATE 3 #define SRSLTE_TCOD_RATE 3
#define SRSLTE_TCOD_TOTALTAIL 12 #define SRSLTE_TCOD_TOTALTAIL 12
@ -67,7 +68,8 @@ typedef struct SRSLTE_API {
srslte_llr_t *syst; srslte_llr_t *syst;
srslte_llr_t *parity; 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_tdec_t;
SRSLTE_API int srslte_tdec_init(srslte_tdec_t * h, SRSLTE_API int srslte_tdec_init(srslte_tdec_t * h,

@ -49,7 +49,7 @@
#define SRSLTE_RAR_GRANT_LEN 20 #define SRSLTE_RAR_GRANT_LEN 20
typedef enum { typedef enum {
SRSLTE_DCI_FORMAT0, SRSLTE_DCI_FORMAT0 = 0,
SRSLTE_DCI_FORMAT1, SRSLTE_DCI_FORMAT1,
SRSLTE_DCI_FORMAT1A, SRSLTE_DCI_FORMAT1A,
SRSLTE_DCI_FORMAT1C, 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, SRSLTE_API uint32_t srslte_dci_format_sizeof(srslte_dci_format_t format,
uint32_t nof_prb); uint32_t nof_prb);
SRSLTE_API uint32_t srslte_dci_format_sizeof_lut(srslte_dci_format_t format,
uint32_t nof_prb);
#endif // DCI_ #endif // DCI_

@ -39,14 +39,14 @@
#include <stdio.h> #include <stdio.h>
#include "srslte/config.h" #include "srslte/config.h"
#define SRSLTE_VERBOSE_DEBUG 2 #define SRSLTE_VERBOSE_DEBUG 2
#define SRSLTE_VERBOSE_INFO 1 #define SRSLTE_VERBOSE_INFO 1
#define SRSLTE_VERBOSE_NONE 0 #define SRSLTE_VERBOSE_NONE 0
#include <sys/time.h> #include <sys/time.h>
SRSLTE_API void get_time_interval(struct timeval * tdata); SRSLTE_API void get_time_interval(struct timeval * tdata);
#ifndef SRSLTE_DEBUG_DISABLED #define SRSLTE_DEBUG_ENABLED 0
SRSLTE_API extern int srslte_verbose; 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_INFO srslte_verbose=SRSLTE_VERBOSE_INFO
#define PRINT_NONE srslte_verbose=SRSLTE_VERBOSE_NONE #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__) 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__) fprintf(stdout, "[INFO]: " _fmt, __VA_ARGS__)
#else // SRSLTE_DEBUG_DISABLED
#define DEBUG
#define INFO
#endif // SRSLTE_DEBUG_DISABLED
#endif // DEBUG_H #endif // DEBUG_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) */ /* 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); 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 */ /* 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_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); SRSLTE_API cf_t srslte_vec_dot_prod_ccc(cf_t *x, cf_t *y, uint32_t len);

@ -83,6 +83,9 @@ int srslte_sequence_LTE_pr(srslte_sequence_t *q, uint32_t len, uint32_t seed) {
q->len = len; q->len = len;
srslte_sequence_set_LTE_pr(q, seed); srslte_sequence_set_LTE_pr(q, seed);
srslte_bit_pack_vector(q->c, q->c_bytes, len); srslte_bit_pack_vector(q->c, q->c_bytes, len);
for (int i=0;i<len;i++) {
q->c_float[i] = (1-2*q->c[i]);
}
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
@ -92,6 +95,9 @@ int srslte_sequence_init(srslte_sequence_t *q, uint32_t len) {
if (q->c_bytes) { if (q->c_bytes) {
free(q->c_bytes); free(q->c_bytes);
} }
if (q->c_float) {
free(q->c_float);
}
} }
if (!q->c) { if (!q->c) {
q->c = srslte_vec_malloc(len * sizeof(uint8_t)); 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) { if (!q->c_bytes) {
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
q->c_float = srslte_vec_malloc(len * sizeof(float));
if (!q->c_float) {
return SRSLTE_ERROR;
}
q->len = len; q->len = len;
} }
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
@ -114,6 +124,9 @@ void srslte_sequence_free(srslte_sequence_t *q) {
if (q->c_bytes) { if (q->c_bytes) {
free(q->c_bytes); free(q->c_bytes);
} }
if (q->c_float) {
free(q->c_float);
}
bzero(q, sizeof(srslte_sequence_t)); bzero(q, sizeof(srslte_sequence_t));
} }

@ -49,9 +49,6 @@ static bool table_initiated = false;
int srslte_tcod_init(srslte_tcod_t *h, uint32_t max_long_cb) { 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->max_long_cb = max_long_cb;
h->temp = srslte_vec_malloc(max_long_cb/8); 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) { void srslte_tcod_free(srslte_tcod_t *h) {
srslte_tc_interl_free(&h->interl);
h->max_long_cb = 0; h->max_long_cb = 0;
if (h->temp) { if (h->temp) {
free(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; return -1;
} }
if (srslte_tc_interl_LTE_gen(&h->interl, long_cb)) { int longcb_idx = srslte_cbsegm_cbindex(long_cb);
fprintf(stderr, "Error initiating TC interleaver\n"); if (longcb_idx < 0) {
fprintf(stderr, "Invalid CB size %d\n", long_cb);
return -1; return -1;
} }
per = h->interl.forward; per = tcod_per_fw[longcb_idx];
reg1_0 = 0; reg1_0 = 0;
reg1_1 = 0; reg1_1 = 0;

@ -239,10 +239,13 @@ int srslte_tdec_init(srslte_tdec_t * h, uint32_t max_long_cb)
goto clean_and_exit; goto clean_and_exit;
} }
if (srslte_tc_interl_init(&h->interleaver, h->max_long_cb) < 0) { for (int i=0;i<SRSLTE_NOF_TC_CB_SIZES;i++) {
goto clean_and_exit; if (srslte_tc_interl_init(&h->interleaver[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; ret = 0;
clean_and_exit:if (ret == -1) { clean_and_exit:if (ret == -1) {
srslte_tdec_free(h); srslte_tdec_free(h);
@ -270,7 +273,9 @@ void srslte_tdec_free(srslte_tdec_t * h)
srslte_map_gen_free(&h->dec); srslte_map_gen_free(&h->dec);
srslte_tc_interl_free(&h->interleaver); for (int i=0;i<SRSLTE_NOF_TC_CB_SIZES;i++) {
srslte_tc_interl_free(&h->interleaver[i]);
}
bzero(h, sizeof(srslte_tdec_t)); 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; uint32_t i;
// Prepare systematic and parity bits for MAP DEC #1 if (h->current_cbidx >= 0) {
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];
}
// Run MAP DEC #1 uint32_t *inter = h->interleaver[h->current_cbidx].forward;
srslte_map_gen_dec(&h->dec, h->syst, h->parity, h->llr1, long_cb); uint32_t *deinter = h->interleaver[h->current_cbidx].reverse;
// Prepare systematic and parity bits for MAP DEC #1 // Prepare systematic and parity bits for MAP DEC #1
for (i = 0; i < long_cb; i++) { for (i = 0; i < long_cb; i++) {
h->syst[i] = h->llr1[h->interleaver.forward[i]] h->syst[i] = input[SRSLTE_TCOD_RATE * i] + h->w[i];
- h->w[h->interleaver.forward[i]]; h->parity[i] = input[SRSLTE_TCOD_RATE * i + 1];
h->parity[i] = input[SRSLTE_TCOD_RATE * i + 2]; }
} for (i = long_cb; i < long_cb + SRSLTE_TCOD_RATE; i++) {
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->syst[i] = h->parity[i] = input[SRSLTE_TCOD_RATE * long_cb + NINPUTS * (i - long_cb) + 1];
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 // Run MAP DEC #1
srslte_map_gen_dec(&h->dec, h->syst, h->parity, h->llr2, long_cb); srslte_map_gen_dec(&h->dec, h->syst, h->parity, h->llr1, long_cb);
// Update a-priori LLR from the last iteration // Prepare systematic and parity bits for MAP DEC #1
for (i = 0; i < long_cb; i++) { for (i = 0; i < long_cb; i++) {
h->w[i] += h->llr2[h->interleaver.reverse[i]] - h->llr1[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) 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; return -1;
} }
memset(h->w, 0, sizeof(srslte_llr_t) * long_cb); 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) 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; uint32_t i;
for (i = 0; i < long_cb; 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) 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 // long_cb is always byte aligned
for (i = 0; i < long_cb/8; i++) { for (i = 0; i < long_cb/8; i++) {
output[i] = 0; uint8_t out0 = h->llr2[deinter[8*i+0]]>0?mask[0]:0;
for (j=0;j<8;j++) { uint8_t out1 = h->llr2[deinter[8*i+1]]>0?mask[1]:0;
if (h->llr2[h->interleaver.reverse[8*i+j]] > 0) { uint8_t out2 = h->llr2[deinter[8*i+2]]>0?mask[2]:0;
output[i] |= 1<<(7-j); 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;
} }
} }

@ -91,12 +91,19 @@ int srslte_demod_soft_demodulate(srslte_demod_soft_t *q, const cf_t* symbols, fl
break; break;
case SRSLTE_DEMOD_SOFT_ALG_APPROX: case SRSLTE_DEMOD_SOFT_ALG_APPROX:
if (nsymbols <= q->max_symbols) { 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->nbits_x_symbol,
q->table->symbol_table, q->table->soft_table.idx, q->table->symbol_table, q->table->soft_table.idx,
q->table->soft_table.d_idx, q->table->soft_table.min_idx, q->sigma, q->table->soft_table.d_idx, q->table->soft_table.min_idx, q->sigma,
q->zones, q->dd); q->zones, q->dd);
break;
}
} else { } else {
fprintf(stderr, "Too many symbols (%d>%d)\n", nsymbols, q->max_symbols); fprintf(stderr, "Too many symbols (%d>%d)\n", nsymbols, q->max_symbols);
return -1; return -1;

@ -40,14 +40,14 @@ time_t start, finish;
struct timeval x, y; struct timeval x, y;
int num_bits = 1000; int num_bits = 1000;
srslte_mod_t modulation; srslte_mod_t modulation = SRSLTE_MOD_BPSK;
bool soft_output = false, soft_exact = false; bool soft_output = true, soft_exact = false;
void usage(char *prog) { void usage(char *prog) {
printf("Usage: %s [nmse]\n", prog); printf("Usage: %s [nmse]\n", prog);
printf("\t-n num_bits [Default %d]\n", num_bits); 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-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"); printf("\t-e soft outputs exact algorithm [Default approx]\n");
} }
@ -99,11 +99,7 @@ int main(int argc, char **argv) {
srslte_demod_soft_t demod_soft; srslte_demod_soft_t demod_soft;
uint8_t *input, *input_bytes, *output; uint8_t *input, *input_bytes, *output;
cf_t *symbols, *symbols_bytes; 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); parse_args(argc, argv);
@ -163,6 +159,12 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
llr2 = srslte_vec_malloc(sizeof(float) * num_bits);
if (!llr2) {
perror("malloc");
exit(-1);
}
/* generate random data */ /* generate random data */
for (i=0;i<num_bits;i++) { for (i=0;i<num_bits;i++) {
input[i] = rand()%2; input[i] = rand()%2;

@ -40,6 +40,7 @@
#include "srslte/utils/vector.h" #include "srslte/utils/vector.h"
#include "srslte/utils/debug.h" #include "srslte/utils/debug.h"
#include "dci_sz_table.h"
/* Unpacks a DCI message and configures the DL grant object /* Unpacks a DCI message and configures the DL grant object
*/ */
@ -301,6 +302,13 @@ uint32_t srslte_dci_format_sizeof(srslte_dci_format_t format, uint32_t nof_prb)
} }
} }
uint32_t srslte_dci_format_sizeof_lut(srslte_dci_format_t format, uint32_t nof_prb) {
if (nof_prb < 100 && format < 4) {
return dci_sz_table[nof_prb][format];
} else {
return 0;
}
}
/********************************** /**********************************
* DCI Resource Allocation functions * DCI Resource Allocation functions
* ********************************/ * ********************************/
@ -361,7 +369,7 @@ int dci_format0_pack(srslte_ra_ul_dci_t *data, srslte_dci_msg_t *msg, uint32_t n
*y++ = data->cqi_request; *y++ = data->cqi_request;
// Padding with zeros // 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) { while (y - msg->data < n) {
*y++ = 0; *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; uint32_t n_ul_hop;
/* Make sure it's a SRSLTE_DCI_FORMAT0 message */ /* 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"); fprintf(stderr, "Invalid message length for format 0\n");
return SRSLTE_ERROR; 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; *y++ = 0;
// Padding with zeros // 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) { while (y - msg->data < n) {
*y++ = 0; *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; uint8_t *y = msg->data;
/* Make sure it's a SRSLTE_DCI_FORMAT1 message */ /* 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"); fprintf(stderr, "Invalid message length for format 1\n");
return SRSLTE_ERROR; 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 // 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) { while (y - msg->data < n) {
*y++ = 0; *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; uint8_t *y = msg->data;
/* Make sure it's a SRSLTE_DCI_FORMAT0 message */ /* 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"); fprintf(stderr, "Invalid message length for format 1A\n");
return SRSLTE_ERROR; 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 */ /* pack bits */
uint8_t *y = msg->data; 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"); fprintf(stderr, "Invalid message length for format 1C\n");
return SRSLTE_ERROR; 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, 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) { 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); 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); 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); return dci_format1Cs_unpack(msg, data, nof_prb);
} else { } else {
return SRSLTE_ERROR; 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) uint16_t msg_rnti)
{ {
DEBUG("Get message type: nof_bits=%d, msg_rnti=0x%x\n", msg->nof_bits, 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]) { && !msg->data[0]) {
type->type = SRSLTE_DCI_MSG_TYPE_PUSCH_SCHED; type->type = SRSLTE_DCI_MSG_TYPE_PUSCH_SCHED;
type->format = SRSLTE_DCI_FORMAT0; type->format = SRSLTE_DCI_FORMAT0;
return SRSLTE_SUCCESS; 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->type = SRSLTE_DCI_MSG_TYPE_PDSCH_SCHED; // only these 2 types supported
type->format = SRSLTE_DCI_FORMAT1; type->format = SRSLTE_DCI_FORMAT1;
return SRSLTE_SUCCESS; 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. /* The RNTI is not the only condition. Also some fields in the packet.
* if (msg_rnti >= SRSLTE_CRNTI_START && msg_rnti <= SRSLTE_CRNTI_END) { * if (msg_rnti >= SRSLTE_CRNTI_START && msg_rnti <= SRSLTE_CRNTI_END) {
type->type = SRSLTE_DCI_MSG_TYPE_RA_PROC_PDCCH; 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; type->format = SRSLTE_DCI_FORMAT1A;
//} //}
return SRSLTE_SUCCESS; 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) { if (msg_rnti == SRSLTE_MRNTI) {
type->type = SRSLTE_DCI_MSG_TYPE_MCCH_CHANGE; type->type = SRSLTE_DCI_MSG_TYPE_MCCH_CHANGE;
type->format = SRSLTE_DCI_FORMAT1C; type->format = SRSLTE_DCI_FORMAT1C;

@ -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}
};

@ -333,7 +333,7 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t *q,
fprintf(stderr, "Invalid location: nCCE: %d, L: %d, NofCCE: %d\n", fprintf(stderr, "Invalid location: nCCE: %d, L: %d, NofCCE: %d\n",
location->ncce, location->L, q->nof_cce); location->ncce, location->L, q->nof_cce);
} else { } 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); 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", DEBUG("Decoding DCI offset %d, e_bits: %d, msg_len %d (nCCE: %d, L: %d)\n",
@ -424,7 +424,8 @@ int srslte_pdcch_extract_llr(srslte_pdcch_t *q, cf_t *sf_symbols, cf_t *ce[SRSLT
} }
/* demodulate symbols */ /* 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); srslte_demod_soft_demodulate(&q->demod, q->d, q->llr, nof_symbols);
/* descramble */ /* descramble */

@ -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 /** 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, 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; return SRSLTE_ERROR;
} }
if (rnti != q->rnti) { if (rnti != q->rnti || !q->rnti_is_set) {
srslte_sequence_t seq; srslte_sequence_t seq;
if (srslte_sequence_pusch(&seq, rnti, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) { if (srslte_sequence_pusch(&seq, rnti, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) {
return SRSLTE_ERROR; return SRSLTE_ERROR;

@ -43,19 +43,21 @@ srslte_cell_t cell = {
}; };
uint32_t cfi = 1; uint32_t cfi = 1;
bool print_dci_table;
void usage(char *prog) { 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-c cell id [Default %d]\n", cell.id);
printf("\t-f cfi [Default %d]\n", cfi); printf("\t-f cfi [Default %d]\n", cfi);
printf("\t-p cell.nof_ports [Default %d]\n", cell.nof_ports); 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-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"); printf("\t-v [set srslte_verbose to debug, default none]\n");
} }
void parse_args(int argc, char **argv) { void parse_args(int argc, char **argv) {
int opt; int opt;
while ((opt = getopt(argc, argv, "cell.cpnfv")) != -1) { while ((opt = getopt(argc, argv, "cfpndv")) != -1) {
switch (opt) { switch (opt) {
case 'p': case 'p':
cell.nof_ports = atoi(argv[optind]); cell.nof_ports = atoi(argv[optind]);
@ -69,6 +71,9 @@ void parse_args(int argc, char **argv) {
case 'c': case 'c':
cell.id = atoi(argv[optind]); cell.id = atoi(argv[optind]);
break; break;
case 'd':
print_dci_table = true;
break;
case 'v': case 'v':
srslte_verbose++; srslte_verbose++;
break; 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(" %2d:\t%2d\t%2d\t%2d\t%2d\n", n, x[0], x[1], x[2], x[3]);
} }
printf("Ok\n"); 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; return 0;
} }

@ -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) { void srslte_scrambling_f_offset(srslte_sequence_t *s, float *data, int offset, int len) {
int i;
assert (len + offset <= s->len); assert (len + offset <= s->len);
srslte_vec_prod_fff(data, &s->c_float[offset], data, len);
for (i = 0; i < len; i++) {
data[i] = data[i] * (1-2*s->c[i + offset]);
}
} }
void srslte_scrambling_c(srslte_sequence_t *s, cf_t *data) { 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) { void srslte_scrambling_c_offset(srslte_sequence_t *s, cf_t *data, int offset, int len) {
int i;
assert (len + offset <= s->len); assert (len + offset <= s->len);
srslte_vec_prod_cfc(data, &s->c_float[offset], data, len);
for (i = 0; i < len; i++) {
data[i] = data[i] * (1 - 2 * s->c[i + offset]);
}
} }
void scrambling_b(uint8_t *c, uint8_t *data, int offset, int len) { void scrambling_b(uint8_t *c, uint8_t *data, int offset, int len) {

@ -381,6 +381,17 @@ void srslte_vec_prod_cfc(cf_t *x, float *y, cf_t *z, uint32_t len) {
#endif #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<len;i++) {
z[i] = x[i]*y[i];
}
#else
volk_32f_x2_multiply_32f(z,x,y,len);
#endif
}
void srslte_vec_prod_ccc(cf_t *x,cf_t *y, cf_t *z, uint32_t len) { void srslte_vec_prod_ccc(cf_t *x,cf_t *y, cf_t *z, uint32_t len) {
#ifndef HAVE_VOLK_MULT2_FUNCTION #ifndef HAVE_VOLK_MULT2_FUNCTION
int i; int i;

Loading…
Cancel
Save