Skip to content

Commit

Permalink
Merge pull request #6 from ismagom/soft_demod_volk
Browse files Browse the repository at this point in the history
Soft demod volk
  • Loading branch information
Ismael Gómez-Miguelez committed Aug 4, 2014
2 parents 81a5d42 + 3448deb commit 1cbbbe9
Show file tree
Hide file tree
Showing 12 changed files with 722 additions and 46 deletions.
4 changes: 4 additions & 0 deletions cmake/modules/FindVolk.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ CHECK_FUNCTION_EXISTS_MATH(volk_32fc_s32f_atan2_32f HAVE_VOLK_ATAN_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32f_s32f_convert_16i HAVE_VOLK_CONVERT_FI_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32fc_deinterleave_32f_x2 HAVE_VOLK_DEINTERLEAVE_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_subtract_32f HAVE_VOLK_SUB_FLOAT_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_index_max_16u HAVE_VOLK_MAX_ABS_FUNCTION)

Expand All @@ -55,6 +56,9 @@ ENDIF()
IF(${HAVE_VOLK_DOTPROD_CONJ_FC_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DOTPROD_CONJ_FC_FUNCTION")
ENDIF()
IF(${HAVE_VOLK_SQUARE_DIST_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_SQUARE_DIST_FUNCTION")
ENDIF()
IF(${HAVE_VOLK_DEINTERLEAVE_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DEINTERLEAVE_FUNCTION")
ENDIF()
Expand Down
9 changes: 6 additions & 3 deletions lte/phy/include/liblte/phy/modem/modem_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,15 @@
typedef _Complex float cf_t;
typedef struct LIBLTE_API {
uint32_t idx[2][6][32];
uint32_t min_idx[2][64][6]; /* NEW: for each constellation point zone (2, 4, 16, 64 for BPSK, QPSK, 16QAM, 64QAM) the 2x(1, 2, 4, and 6 closest constellation points) for each bit, respectively. */
uint32_t d_idx[64][7]; /* NEW: for each constellation point zone (2, 4, 16, 64 for BPSK, QPSK, 16QAM, 64QAM) the 2, 3, 5 and 7 indices to constellation points that need to be computed for any recevied symbol modulated as BPSK, QPSK, 16QAM, and 64QAM, respectively. */

}soft_table_t;

typedef struct LIBLTE_API {
cf_t* symbol_table; // bit-to-symbol mapping
soft_table_t soft_table; // symbol-to-bit mapping (used in soft demodulating)
uint32_t nsymbols; // number of modulation symbols
cf_t* symbol_table; // bit-to-symbol mapping
soft_table_t soft_table; // symbol-to-bit mapping (used in soft demodulating)
uint32_t nsymbols; // number of modulation symbols
uint32_t nbits_x_symbol; // number of bits per symbol
}modem_table_t;

Expand Down
5 changes: 4 additions & 1 deletion lte/phy/include/liblte/phy/utils/vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

typedef _Complex float cf_t;

#define EXPAVERAGE(data, average, nframes) ((data + average * nframes) / (nframes + 1))
#define EXPAVERAGE(data, average, nframes) (((data) + (average) * (nframes)) / ((nframes) + 1))


/** Return the sum of all the elements */
Expand Down Expand Up @@ -64,6 +64,9 @@ LIBLTE_API void vec_sum_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len);
/* substract two vectors z=x-y */
LIBLTE_API void vec_sub_fff(float *x, float *y, float *z, uint32_t len);

/* Square distance */
LIBLTE_API void vec_square_dist(cf_t symbol, cf_t *points, float *distance, uint32_t npoints);

/* scalar product */
LIBLTE_API void vec_sc_prod_cfc(cf_t *x, float h, cf_t *z, uint32_t len);
LIBLTE_API void vec_sc_prod_ccc(cf_t *x, cf_t h, cf_t *z, uint32_t len);
Expand Down
4 changes: 3 additions & 1 deletion lte/phy/lib/modem/src/demod_soft.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ int demod_soft_demodulate(demod_soft_t *q, const cf_t* symbols, float* llr, int
q->table->symbol_table, q->table->soft_table.idx, q->sigma);
break;
case APPROX:
llr_approx(symbols, llr, nsymbols, q->table->nsymbols, q->table->nbits_x_symbol,
/* llr_approx(symbols, llr, nsymbols, q->table->nsymbols, q->table->nbits_x_symbol,
q->table->symbol_table, q->table->soft_table.idx, q->sigma);
*/ 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);
break;
}
return nsymbols*q->table->nbits_x_symbol;
Expand Down
110 changes: 110 additions & 0 deletions lte/phy/lib/modem/src/lte_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#include "liblte/phy/modem/modem_table.h"
#include "lte_tables.h"

void LLR_approx_params(const cf_t* table, soft_table_t *soft_table, int B);

/**
* Set the BPSK modulation table */
void set_BPSKtable(cf_t* table, soft_table_t *soft_table, bool compute_soft_demod)
Expand All @@ -53,6 +55,18 @@ void set_BPSKtable(cf_t* table, soft_table_t *soft_table, bool compute_soft_demo
/* BSPK symbols containing a '0' and a '1' (only two symbols, 1 bit) */
soft_table->idx[0][0][0] = 0;
soft_table->idx[1][0][0] = 1;

/* set two matrices for LLR approx. calculation */
soft_table->min_idx[0][0][0] = 0;
soft_table->min_idx[0][1][0] = 0;
soft_table->min_idx[1][0][0] = 1;
soft_table->min_idx[1][1][0] = 1;

soft_table->d_idx[0][0] = 0;
soft_table->d_idx[0][1] = 1;
soft_table->d_idx[1][0] = 0;
soft_table->d_idx[1][1] = 1;

}

/**
Expand Down Expand Up @@ -91,6 +105,8 @@ void set_QPSKtable(cf_t* table, soft_table_t *soft_table, bool compute_soft_demo
soft_table->idx[1][0][1] = 3;
soft_table->idx[1][1][0] = 1;
soft_table->idx[1][1][1] = 3;

LLR_approx_params(table, soft_table, 2); /* last param indicating B (bits per symbol) */
}

/**
Expand Down Expand Up @@ -156,6 +172,8 @@ void set_16QAMtable(cf_t* table, soft_table_t *soft_table, bool compute_soft_dem
soft_table->idx[0][3][i] = 2*i;
soft_table->idx[1][3][i] = 2*i+1;
}

LLR_approx_params(table, soft_table, 4); /* last param indication B (bits per symbol) */
}

/**
Expand Down Expand Up @@ -277,4 +295,96 @@ void set_64QAMtable(cf_t* table, soft_table_t *soft_table, bool compute_soft_dem
soft_table->idx[0][5][i] = 2*i;
soft_table->idx[1][5][i] = 2*i+1;
}

LLR_approx_params(table, soft_table, 6); /* last param indication modulation */
}

/* Precompute two tables for calculating the distances based on the received symbol location relative to the constellation points */
void LLR_approx_params(const cf_t* table, soft_table_t *soft_table, int B) {

int i, j, b, k;
float x, y, d0, d1, min_d0, min_d1;
int M, D;
uint32_t min_idx0[64][6], min_idx1[64][6];
uint32_t count;
int flag;


D = B+1; /* number of different distances to be computed */
//M = pow(2,B); /* number of constellation points */
switch (B) {
case 1: {M = 2; break;} /* BPSK */
case 2: {M = 4; break;} /* QPSK */
case 4: {M = 16; break;} /* 16QAM */
case 6: {M = 64; break;} /* 64QAM */
default: {M = 4; break;} /* QPSK */
}

for (i=0;i<M;i++) { /* constellation points */
for (b=0;b<B;b++) { /* bits per symbol */
min_d0 = 100;
min_d1 = 100;

for (j=0;j<M/2;j++) { /* half the symbols have a '0', the other half a '1' at any bit position of modulation symbol */
x = __real__ table[i] - __real__ table[soft_table->idx[0][b][j]];
y = __imag__ table[i] - __imag__ table[soft_table->idx[0][b][j]];
d0 = x*x + y*y;
if (d0 < min_d0) {
min_d0 = d0;
min_idx0[i][b] = soft_table->idx[0][b][j];
}

x = __real__ table[i] - __real__ table[soft_table->idx[1][b][j]];
y = __imag__ table[i] - __imag__ table[soft_table->idx[1][b][j]];
d1 = x*x + y*y;
if (d1 < min_d1) {
min_d1 = d1;
min_idx1[i][b] = soft_table->idx[1][b][j];
}
}
}
}

for (i=0;i<M;i++) {
for (j=0;j<D;j++) {
soft_table->d_idx[i][j] = -1; /* intialization */
}
}

for (i=0;i<M;i++) {
count = 0;
for (b=0;b<B;b++) { /* bit(b) = 0 */
flag = 0;
for (k=0;k<count;k++) {
if (min_idx0[i][b] == soft_table->d_idx[i][k]) {
soft_table->min_idx[0][i][b] = k;
flag = 1; /* no new entry to idxdx */
break;
}
}

if (flag == 0) { /* new entry to min and d_idx */
soft_table->d_idx[i][count] = min_idx0[i][b];
soft_table->min_idx[0][i][b] = count;
count++;
}
}
for (b=0;b<B;b++) { /* bit(b) = 1 */
flag = 0;
for (k=0;k<count;k++) {
if (min_idx1[i][b] == soft_table->d_idx[i][k]) {
soft_table->min_idx[1][i][b] = k;
flag = 1; /* no new entry to d_idx */
break;
}
}

if (flag == 0) { /* new entry to min and d_idx */
soft_table->d_idx[i][count] = min_idx1[i][b];
soft_table->min_idx[1][i][b] = count;
count++;
}
}
}
}

8 changes: 8 additions & 0 deletions lte/phy/lib/modem/src/lte_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@
#define QAM64_LEVEL_3 5/sqrt(42)
#define QAM64_LEVEL_4 7/sqrt(42)

//////////////// NUEVO //////////////////////
/* HARD DEMODULATION Thresholds, necessary for obtaining the zone of received symbol for optimized LLR approx implementation */
#define QAM16_THRESHOLD 2/sqrt(10)
#define QAM64_THRESHOLD_1 2/sqrt(42)
#define QAM64_THRESHOLD_2 4/sqrt(42)
#define QAM64_THRESHOLD_3 6/sqrt(42)
//=========================================//

#define QAM64_LEVEL_x 2/sqrt(42)
/* this is not an QAM64 level, but, rather, an auxiliary value that can be used for computing the
* symbol from the bit sequence */
Expand Down
Loading

0 comments on commit 1cbbbe9

Please sign in to comment.