clang format, similar to GNU Radio
This commit is contained in:
+42
-68
@@ -21,85 +21,59 @@
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
base::base() :
|
||||
d_store_pos(0) {
|
||||
}
|
||||
base::base() : d_store_pos(0) {}
|
||||
|
||||
base::~base() {
|
||||
}
|
||||
base::~base() {}
|
||||
|
||||
uint8_t*
|
||||
base::depuncture(uint8_t *in) {
|
||||
uint8_t* base::depuncture(uint8_t* in)
|
||||
{
|
||||
|
||||
int count;
|
||||
int n_cbps = d_ofdm->n_cbps;
|
||||
uint8_t *depunctured;
|
||||
int count;
|
||||
int n_cbps = d_ofdm->n_cbps;
|
||||
uint8_t* depunctured;
|
||||
|
||||
if (d_ntraceback == 5) {
|
||||
count = d_frame->n_sym * n_cbps;
|
||||
depunctured = in;
|
||||
if (d_ntraceback == 5) {
|
||||
count = d_frame->n_sym * n_cbps;
|
||||
depunctured = in;
|
||||
|
||||
} else {
|
||||
depunctured = d_depunctured;
|
||||
count = 0;
|
||||
for(int i = 0; i < d_frame->n_sym; i++) {
|
||||
for(int k = 0; k < n_cbps; k++) {
|
||||
while (d_depuncture_pattern[count % (2 * d_k)] == 0) {
|
||||
depunctured[count] = 2;
|
||||
count++;
|
||||
}
|
||||
} else {
|
||||
depunctured = d_depunctured;
|
||||
count = 0;
|
||||
for (int i = 0; i < d_frame->n_sym; i++) {
|
||||
for (int k = 0; k < n_cbps; k++) {
|
||||
while (d_depuncture_pattern[count % (2 * d_k)] == 0) {
|
||||
depunctured[count] = 2;
|
||||
count++;
|
||||
}
|
||||
|
||||
// Insert received bits
|
||||
depunctured[count] = in[i * n_cbps + k];
|
||||
count++;
|
||||
// Insert received bits
|
||||
depunctured[count] = in[i * n_cbps + k];
|
||||
count++;
|
||||
|
||||
while (d_depuncture_pattern[count % (2 * d_k)] == 0) {
|
||||
depunctured[count] = 2;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (d_depuncture_pattern[count % (2 * d_k)] == 0) {
|
||||
depunctured[count] = 2;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return depunctured;
|
||||
return depunctured;
|
||||
}
|
||||
|
||||
/* Parity lookup table */
|
||||
const unsigned char base::PARTAB[256] = {
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 1, 0, 0, 1,
|
||||
1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1,
|
||||
0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0,
|
||||
0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0,
|
||||
1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||
0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0,
|
||||
1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1,
|
||||
1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0,
|
||||
1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||
0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||
};
|
||||
|
||||
const unsigned char base::PUNCTURE_1_2[2] = {1, 1};
|
||||
const unsigned char base::PUNCTURE_2_3[4] = {1, 1, 1, 0};
|
||||
const unsigned char base::PUNCTURE_3_4[6] = {1, 1, 1, 0, 0, 1};
|
||||
const unsigned char base::PUNCTURE_1_2[2] = { 1, 1 };
|
||||
const unsigned char base::PUNCTURE_2_3[4] = { 1, 1, 1, 0 };
|
||||
const unsigned char base::PUNCTURE_3_4[6] = { 1, 1, 1, 0, 0, 1 };
|
||||
|
||||
+22
-23
@@ -33,35 +33,34 @@ namespace ieee802_11 {
|
||||
class base
|
||||
{
|
||||
public:
|
||||
|
||||
base();
|
||||
~base();
|
||||
virtual uint8_t* decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in) = 0;
|
||||
base();
|
||||
~base();
|
||||
virtual uint8_t* decode(ofdm_param* ofdm, frame_param* frame, uint8_t* in) = 0;
|
||||
|
||||
protected:
|
||||
// Position in circular buffer where the current decoded byte is stored
|
||||
int d_store_pos;
|
||||
// Metrics for each state
|
||||
unsigned char d_mmresult[64] __attribute__((aligned(16)));
|
||||
// Paths for each state
|
||||
unsigned char d_ppresult[TRACEBACK_MAX][64] __attribute__((aligned(16)));
|
||||
// Position in circular buffer where the current decoded byte is stored
|
||||
int d_store_pos;
|
||||
// Metrics for each state
|
||||
unsigned char d_mmresult[64] __attribute__((aligned(16)));
|
||||
// Paths for each state
|
||||
unsigned char d_ppresult[TRACEBACK_MAX][64] __attribute__((aligned(16)));
|
||||
|
||||
int d_ntraceback;
|
||||
int d_k;
|
||||
ofdm_param *d_ofdm;
|
||||
frame_param *d_frame;
|
||||
const unsigned char *d_depuncture_pattern;
|
||||
int d_ntraceback;
|
||||
int d_k;
|
||||
ofdm_param* d_ofdm;
|
||||
frame_param* d_frame;
|
||||
const unsigned char* d_depuncture_pattern;
|
||||
|
||||
uint8_t d_depunctured[MAX_ENCODED_BITS];
|
||||
uint8_t d_decoded[MAX_ENCODED_BITS * 3 / 4];
|
||||
uint8_t d_depunctured[MAX_ENCODED_BITS];
|
||||
uint8_t d_decoded[MAX_ENCODED_BITS * 3 / 4];
|
||||
|
||||
static const unsigned char PARTAB[256];
|
||||
static const unsigned char PUNCTURE_1_2[2];
|
||||
static const unsigned char PUNCTURE_2_3[4];
|
||||
static const unsigned char PUNCTURE_3_4[6];
|
||||
static const unsigned char PARTAB[256];
|
||||
static const unsigned char PUNCTURE_1_2[2];
|
||||
static const unsigned char PUNCTURE_2_3[4];
|
||||
static const unsigned char PUNCTURE_3_4[6];
|
||||
|
||||
virtual void reset() = 0;
|
||||
uint8_t* depuncture(uint8_t *in);
|
||||
virtual void reset() = 0;
|
||||
uint8_t* depuncture(uint8_t* in);
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
|
||||
@@ -56,371 +56,381 @@
|
||||
* would spill over into memory.
|
||||
*/
|
||||
|
||||
#define BUTTERFLY(i,sym) { \
|
||||
int m0,m1,m2,m3; \
|
||||
/* ACS for 0 branch */ \
|
||||
m0 = state[i].metric + mets[sym]; /* 2*i */ \
|
||||
m1 = state[i+32].metric + mets[3 ^ sym]; /* 2*i + 64 */ \
|
||||
if(m0 > m1){ \
|
||||
next[2*i].metric = m0; \
|
||||
next[2*i].path = state[i].path << 1; \
|
||||
} else { \
|
||||
next[2*i].metric = m1; \
|
||||
next[2*i].path = (state[i+32].path << 1)|1; \
|
||||
} \
|
||||
/* ACS for 1 branch */ \
|
||||
m2 = state[i].metric + mets[3 ^ sym]; /* 2*i + 1 */ \
|
||||
m3 = state[i+32].metric + mets[sym]; /* 2*i + 65 */ \
|
||||
if(m2 > m3){ \
|
||||
next[2*i+1].metric = m2; \
|
||||
next[2*i+1].path = state[i].path << 1; \
|
||||
} else { \
|
||||
next[2*i+1].metric = m3; \
|
||||
next[2*i+1].path = (state[i+32].path << 1)|1; \
|
||||
} \
|
||||
}
|
||||
#define BUTTERFLY(i, sym) \
|
||||
{ \
|
||||
int m0, m1, m2, m3; \
|
||||
/* ACS for 0 branch */ \
|
||||
m0 = state[i].metric + mets[sym]; /* 2*i */ \
|
||||
m1 = state[i + 32].metric + mets[3 ^ sym]; /* 2*i + 64 */ \
|
||||
if (m0 > m1) { \
|
||||
next[2 * i].metric = m0; \
|
||||
next[2 * i].path = state[i].path << 1; \
|
||||
} else { \
|
||||
next[2 * i].metric = m1; \
|
||||
next[2 * i].path = (state[i + 32].path << 1) | 1; \
|
||||
} \
|
||||
/* ACS for 1 branch */ \
|
||||
m2 = state[i].metric + mets[3 ^ sym]; /* 2*i + 1 */ \
|
||||
m3 = state[i + 32].metric + mets[sym]; /* 2*i + 65 */ \
|
||||
if (m2 > m3) { \
|
||||
next[2 * i + 1].metric = m2; \
|
||||
next[2 * i + 1].path = state[i].path << 1; \
|
||||
} else { \
|
||||
next[2 * i + 1].metric = m3; \
|
||||
next[2 * i + 1].path = (state[i + 32].path << 1) | 1; \
|
||||
} \
|
||||
}
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
|
||||
void
|
||||
viterbi_decoder::viterbi_butterfly2_generic(unsigned char *symbols,
|
||||
unsigned char *mm0, unsigned char *mm1, unsigned char *pp0,
|
||||
unsigned char *pp1)
|
||||
void viterbi_decoder::viterbi_butterfly2_generic(unsigned char* symbols,
|
||||
unsigned char* mm0,
|
||||
unsigned char* mm1,
|
||||
unsigned char* pp0,
|
||||
unsigned char* pp1)
|
||||
{
|
||||
int i, j, k;
|
||||
int i, j, k;
|
||||
|
||||
unsigned char *metric0, *metric1;
|
||||
unsigned char *path0, *path1;
|
||||
unsigned char *metric0, *metric1;
|
||||
unsigned char *path0, *path1;
|
||||
|
||||
metric0 = mm0;
|
||||
path0 = pp0;
|
||||
metric1 = mm1;
|
||||
path1 = pp1;
|
||||
metric0 = mm0;
|
||||
path0 = pp0;
|
||||
metric1 = mm1;
|
||||
path1 = pp1;
|
||||
|
||||
// Operate on 4 symbols (2 bits) at a time
|
||||
// Operate on 4 symbols (2 bits) at a time
|
||||
|
||||
unsigned char m0[16], m1[16], m2[16], m3[16], decision0[16], decision1[16], survivor0[16], survivor1[16];
|
||||
unsigned char metsv[16], metsvm[16];
|
||||
unsigned char shift0[16], shift1[16];
|
||||
unsigned char tmp0[16], tmp1[16];
|
||||
unsigned char sym0v[16], sym1v[16];
|
||||
unsigned short simd_epi16;
|
||||
unsigned char m0[16], m1[16], m2[16], m3[16], decision0[16], decision1[16],
|
||||
survivor0[16], survivor1[16];
|
||||
unsigned char metsv[16], metsvm[16];
|
||||
unsigned char shift0[16], shift1[16];
|
||||
unsigned char tmp0[16], tmp1[16];
|
||||
unsigned char sym0v[16], sym1v[16];
|
||||
unsigned short simd_epi16;
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
sym0v[j] = symbols[0];
|
||||
sym1v[j] = symbols[1];
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
sym0v[j] = symbols[0];
|
||||
sym1v[j] = symbols[1];
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (symbols[0] == 2) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
metsvm[j] = d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j];
|
||||
metsv[j] = 1 - metsvm[j];
|
||||
}
|
||||
}
|
||||
else if (symbols[1] == 2) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
metsvm[j] = d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j];
|
||||
metsv[j] = 1 - metsvm[j];
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (j = 0; j < 16; j++) {
|
||||
metsvm[j] = (d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]) + (d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]);
|
||||
metsv[j] = 2 - metsvm[j];
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (symbols[0] == 2) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
metsvm[j] = d_branchtab27_generic[1].c[(i * 16) + j] ^ sym1v[j];
|
||||
metsv[j] = 1 - metsvm[j];
|
||||
}
|
||||
} else if (symbols[1] == 2) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
metsvm[j] = d_branchtab27_generic[0].c[(i * 16) + j] ^ sym0v[j];
|
||||
metsv[j] = 1 - metsvm[j];
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < 16; j++) {
|
||||
metsvm[j] = (d_branchtab27_generic[0].c[(i * 16) + j] ^ sym0v[j]) +
|
||||
(d_branchtab27_generic[1].c[(i * 16) + j] ^ sym1v[j]);
|
||||
metsv[j] = 2 - metsvm[j];
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
m0[j] = metric0[(i*16) + j] + metsv[j];
|
||||
m1[j] = metric0[((i+2)*16) + j] + metsvm[j];
|
||||
m2[j] = metric0[(i*16) + j] + metsvm[j];
|
||||
m3[j] = metric0[((i+2)*16) + j] + metsv[j];
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
m0[j] = metric0[(i * 16) + j] + metsv[j];
|
||||
m1[j] = metric0[((i + 2) * 16) + j] + metsvm[j];
|
||||
m2[j] = metric0[(i * 16) + j] + metsvm[j];
|
||||
m3[j] = metric0[((i + 2) * 16) + j] + metsv[j];
|
||||
}
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0;
|
||||
decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0;
|
||||
survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]);
|
||||
survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]);
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0;
|
||||
decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0;
|
||||
survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]);
|
||||
survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]);
|
||||
}
|
||||
|
||||
for (j = 0; j < 16; j += 2) {
|
||||
simd_epi16 = path0[(i*16) + j];
|
||||
simd_epi16 |= path0[(i*16) + (j+1)] << 8;
|
||||
simd_epi16 <<= 1;
|
||||
shift0[j] = simd_epi16;
|
||||
shift0[j+1] = simd_epi16 >> 8;
|
||||
for (j = 0; j < 16; j += 2) {
|
||||
simd_epi16 = path0[(i * 16) + j];
|
||||
simd_epi16 |= path0[(i * 16) + (j + 1)] << 8;
|
||||
simd_epi16 <<= 1;
|
||||
shift0[j] = simd_epi16;
|
||||
shift0[j + 1] = simd_epi16 >> 8;
|
||||
|
||||
simd_epi16 = path0[((i+2)*16) + j];
|
||||
simd_epi16 |= path0[((i+2)*16) + (j+1)] << 8;
|
||||
simd_epi16 <<= 1;
|
||||
shift1[j] = simd_epi16;
|
||||
shift1[j+1] = simd_epi16 >> 8;
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
shift1[j] = shift1[j] + 1;
|
||||
}
|
||||
simd_epi16 = path0[((i + 2) * 16) + j];
|
||||
simd_epi16 |= path0[((i + 2) * 16) + (j + 1)] << 8;
|
||||
simd_epi16 <<= 1;
|
||||
shift1[j] = simd_epi16;
|
||||
shift1[j + 1] = simd_epi16 >> 8;
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
shift1[j] = shift1[j] + 1;
|
||||
}
|
||||
|
||||
for (j = 0, k = 0; j < 16; j += 2, k++) {
|
||||
metric1[(2*i*16) + j] = survivor0[k];
|
||||
metric1[(2*i*16) + (j+1)] = survivor1[k];
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]);
|
||||
}
|
||||
for (j = 0, k = 0; j < 16; j += 2, k++) {
|
||||
metric1[(2 * i * 16) + j] = survivor0[k];
|
||||
metric1[(2 * i * 16) + (j + 1)] = survivor1[k];
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]);
|
||||
}
|
||||
|
||||
for (j = 0, k = 8; j < 16; j += 2, k++) {
|
||||
metric1[((2*i+1)*16) + j] = survivor0[k];
|
||||
metric1[((2*i+1)*16) + (j+1)] = survivor1[k];
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]);
|
||||
}
|
||||
for (j = 0, k = 8; j < 16; j += 2, k++) {
|
||||
metric1[((2 * i + 1) * 16) + j] = survivor0[k];
|
||||
metric1[((2 * i + 1) * 16) + (j + 1)] = survivor1[k];
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]);
|
||||
}
|
||||
|
||||
for (j = 0, k = 0; j < 16; j += 2, k++) {
|
||||
path1[(2*i*16) + j] = tmp0[k];
|
||||
path1[(2*i*16) + (j+1)] = tmp1[k];
|
||||
}
|
||||
for (j = 0, k = 8; j < 16; j += 2, k++) {
|
||||
path1[((2*i+1)*16) + j] = tmp0[k];
|
||||
path1[((2*i+1)*16) + (j+1)] = tmp1[k];
|
||||
}
|
||||
}
|
||||
for (j = 0, k = 0; j < 16; j += 2, k++) {
|
||||
path1[(2 * i * 16) + j] = tmp0[k];
|
||||
path1[(2 * i * 16) + (j + 1)] = tmp1[k];
|
||||
}
|
||||
for (j = 0, k = 8; j < 16; j += 2, k++) {
|
||||
path1[((2 * i + 1) * 16) + j] = tmp0[k];
|
||||
path1[((2 * i + 1) * 16) + (j + 1)] = tmp1[k];
|
||||
}
|
||||
}
|
||||
|
||||
metric0 = mm1;
|
||||
path0 = pp1;
|
||||
metric1 = mm0;
|
||||
path1 = pp0;
|
||||
metric0 = mm1;
|
||||
path0 = pp1;
|
||||
metric1 = mm0;
|
||||
path1 = pp0;
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
sym0v[j] = symbols[2];
|
||||
sym1v[j] = symbols[3];
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
sym0v[j] = symbols[2];
|
||||
sym1v[j] = symbols[3];
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (symbols[2] == 2) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
metsvm[j] = d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j];
|
||||
metsv[j] = 1 - metsvm[j];
|
||||
}
|
||||
}
|
||||
else if (symbols[3] == 2) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
metsvm[j] = d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j];
|
||||
metsv[j] = 1 - metsvm[j];
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (j = 0; j < 16; j++) {
|
||||
metsvm[j] = (d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]) + (d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]);
|
||||
metsv[j] = 2 - metsvm[j];
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (symbols[2] == 2) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
metsvm[j] = d_branchtab27_generic[1].c[(i * 16) + j] ^ sym1v[j];
|
||||
metsv[j] = 1 - metsvm[j];
|
||||
}
|
||||
} else if (symbols[3] == 2) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
metsvm[j] = d_branchtab27_generic[0].c[(i * 16) + j] ^ sym0v[j];
|
||||
metsv[j] = 1 - metsvm[j];
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < 16; j++) {
|
||||
metsvm[j] = (d_branchtab27_generic[0].c[(i * 16) + j] ^ sym0v[j]) +
|
||||
(d_branchtab27_generic[1].c[(i * 16) + j] ^ sym1v[j]);
|
||||
metsv[j] = 2 - metsvm[j];
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
m0[j] = metric0[(i*16) + j] + metsv[j];
|
||||
m1[j] = metric0[((i+2)*16) + j] + metsvm[j];
|
||||
m2[j] = metric0[(i*16) + j] + metsvm[j];
|
||||
m3[j] = metric0[((i+2)*16) + j] + metsv[j];
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
m0[j] = metric0[(i * 16) + j] + metsv[j];
|
||||
m1[j] = metric0[((i + 2) * 16) + j] + metsvm[j];
|
||||
m2[j] = metric0[(i * 16) + j] + metsvm[j];
|
||||
m3[j] = metric0[((i + 2) * 16) + j] + metsv[j];
|
||||
}
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0;
|
||||
decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0;
|
||||
survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]);
|
||||
survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]);
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0;
|
||||
decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0;
|
||||
survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]);
|
||||
survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]);
|
||||
}
|
||||
|
||||
for (j = 0; j < 16; j += 2) {
|
||||
simd_epi16 = path0[(i*16) + j];
|
||||
simd_epi16 |= path0[(i*16) + (j+1)] << 8;
|
||||
simd_epi16 <<= 1;
|
||||
shift0[j] = simd_epi16;
|
||||
shift0[j+1] = simd_epi16 >> 8;
|
||||
for (j = 0; j < 16; j += 2) {
|
||||
simd_epi16 = path0[(i * 16) + j];
|
||||
simd_epi16 |= path0[(i * 16) + (j + 1)] << 8;
|
||||
simd_epi16 <<= 1;
|
||||
shift0[j] = simd_epi16;
|
||||
shift0[j + 1] = simd_epi16 >> 8;
|
||||
|
||||
simd_epi16 = path0[((i+2)*16) + j];
|
||||
simd_epi16 |= path0[((i+2)*16) + (j+1)] << 8;
|
||||
simd_epi16 <<= 1;
|
||||
shift1[j] = simd_epi16;
|
||||
shift1[j+1] = simd_epi16 >> 8;
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
shift1[j] = shift1[j] + 1;
|
||||
}
|
||||
simd_epi16 = path0[((i + 2) * 16) + j];
|
||||
simd_epi16 |= path0[((i + 2) * 16) + (j + 1)] << 8;
|
||||
simd_epi16 <<= 1;
|
||||
shift1[j] = simd_epi16;
|
||||
shift1[j + 1] = simd_epi16 >> 8;
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
shift1[j] = shift1[j] + 1;
|
||||
}
|
||||
|
||||
for (j = 0, k = 0; j < 16; j += 2, k++) {
|
||||
metric1[(2*i*16) + j] = survivor0[k];
|
||||
metric1[(2*i*16) + (j+1)] = survivor1[k];
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]);
|
||||
}
|
||||
for (j = 0, k = 0; j < 16; j += 2, k++) {
|
||||
metric1[(2 * i * 16) + j] = survivor0[k];
|
||||
metric1[(2 * i * 16) + (j + 1)] = survivor1[k];
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]);
|
||||
}
|
||||
|
||||
for (j = 0, k = 8; j < 16; j += 2, k++) {
|
||||
metric1[((2*i+1)*16) + j] = survivor0[k];
|
||||
metric1[((2*i+1)*16) + (j+1)] = survivor1[k];
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]);
|
||||
}
|
||||
for (j = 0, k = 8; j < 16; j += 2, k++) {
|
||||
metric1[((2 * i + 1) * 16) + j] = survivor0[k];
|
||||
metric1[((2 * i + 1) * 16) + (j + 1)] = survivor1[k];
|
||||
}
|
||||
for (j = 0; j < 16; j++) {
|
||||
tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]);
|
||||
}
|
||||
|
||||
for (j = 0, k = 0; j < 16; j += 2, k++) {
|
||||
path1[(2*i*16) + j] = tmp0[k];
|
||||
path1[(2*i*16) + (j+1)] = tmp1[k];
|
||||
}
|
||||
for (j = 0, k = 8; j < 16; j += 2, k++) {
|
||||
path1[((2*i+1)*16) + j] = tmp0[k];
|
||||
path1[((2*i+1)*16) + (j+1)] = tmp1[k];
|
||||
}
|
||||
}
|
||||
for (j = 0, k = 0; j < 16; j += 2, k++) {
|
||||
path1[(2 * i * 16) + j] = tmp0[k];
|
||||
path1[(2 * i * 16) + (j + 1)] = tmp1[k];
|
||||
}
|
||||
for (j = 0, k = 8; j < 16; j += 2, k++) {
|
||||
path1[((2 * i + 1) * 16) + j] = tmp0[k];
|
||||
path1[((2 * i + 1) * 16) + (j + 1)] = tmp1[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find current best path
|
||||
unsigned char
|
||||
viterbi_decoder::viterbi_get_output_generic(unsigned char *mm0,
|
||||
unsigned char *pp0, int ntraceback, unsigned char *outbuf) {
|
||||
int i;
|
||||
int bestmetric, minmetric;
|
||||
int beststate = 0;
|
||||
int pos = 0;
|
||||
int j;
|
||||
unsigned char viterbi_decoder::viterbi_get_output_generic(unsigned char* mm0,
|
||||
unsigned char* pp0,
|
||||
int ntraceback,
|
||||
unsigned char* outbuf)
|
||||
{
|
||||
int i;
|
||||
int bestmetric, minmetric;
|
||||
int beststate = 0;
|
||||
int pos = 0;
|
||||
int j;
|
||||
|
||||
// circular buffer with the last ntraceback paths
|
||||
d_store_pos = (d_store_pos + 1) % ntraceback;
|
||||
// circular buffer with the last ntraceback paths
|
||||
d_store_pos = (d_store_pos + 1) % ntraceback;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
d_mmresult[(i*16) + j] = mm0[(i*16) + j];
|
||||
d_ppresult[d_store_pos][(i*16) + j] = pp0[(i*16) + j];
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
d_mmresult[(i * 16) + j] = mm0[(i * 16) + j];
|
||||
d_ppresult[d_store_pos][(i * 16) + j] = pp0[(i * 16) + j];
|
||||
}
|
||||
}
|
||||
|
||||
// Find out the best final state
|
||||
bestmetric = d_mmresult[beststate];
|
||||
minmetric = d_mmresult[beststate];
|
||||
// Find out the best final state
|
||||
bestmetric = d_mmresult[beststate];
|
||||
minmetric = d_mmresult[beststate];
|
||||
|
||||
for (i = 1; i < 64; i++) {
|
||||
if (d_mmresult[i] > bestmetric) {
|
||||
bestmetric = d_mmresult[i];
|
||||
beststate = i;
|
||||
}
|
||||
if (d_mmresult[i] < minmetric) {
|
||||
minmetric = d_mmresult[i];
|
||||
}
|
||||
}
|
||||
for (i = 1; i < 64; i++) {
|
||||
if (d_mmresult[i] > bestmetric) {
|
||||
bestmetric = d_mmresult[i];
|
||||
beststate = i;
|
||||
}
|
||||
if (d_mmresult[i] < minmetric) {
|
||||
minmetric = d_mmresult[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Trace back
|
||||
for (i = 0, pos = d_store_pos; i < (ntraceback - 1); i++) {
|
||||
// Obtain the state from the output bits
|
||||
// by clocking in the output bits in reverse order.
|
||||
// The state has only 6 bits
|
||||
beststate = d_ppresult[pos][beststate] >> 2;
|
||||
pos = (pos - 1 + ntraceback) % ntraceback;
|
||||
}
|
||||
// Trace back
|
||||
for (i = 0, pos = d_store_pos; i < (ntraceback - 1); i++) {
|
||||
// Obtain the state from the output bits
|
||||
// by clocking in the output bits in reverse order.
|
||||
// The state has only 6 bits
|
||||
beststate = d_ppresult[pos][beststate] >> 2;
|
||||
pos = (pos - 1 + ntraceback) % ntraceback;
|
||||
}
|
||||
|
||||
// Store output byte
|
||||
*outbuf = d_ppresult[pos][beststate];
|
||||
// Store output byte
|
||||
*outbuf = d_ppresult[pos][beststate];
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
pp0[(i*16) + j] = 0;
|
||||
mm0[(i*16) + j] = mm0[(i*16) + j] - minmetric;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
pp0[(i * 16) + j] = 0;
|
||||
mm0[(i * 16) + j] = mm0[(i * 16) + j] - minmetric;
|
||||
}
|
||||
}
|
||||
|
||||
return bestmetric;
|
||||
return bestmetric;
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
viterbi_decoder::decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in) {
|
||||
uint8_t* viterbi_decoder::decode(ofdm_param* ofdm, frame_param* frame, uint8_t* in)
|
||||
{
|
||||
|
||||
d_ofdm = ofdm;
|
||||
d_frame = frame;
|
||||
d_ofdm = ofdm;
|
||||
d_frame = frame;
|
||||
|
||||
reset();
|
||||
uint8_t *depunctured = depuncture(in);
|
||||
reset();
|
||||
uint8_t* depunctured = depuncture(in);
|
||||
|
||||
int in_count = 0;
|
||||
int out_count = 0;
|
||||
int n_decoded = 0;
|
||||
int in_count = 0;
|
||||
int out_count = 0;
|
||||
int n_decoded = 0;
|
||||
|
||||
while(n_decoded < d_frame->n_data_bits) {
|
||||
while (n_decoded < d_frame->n_data_bits) {
|
||||
|
||||
if ((in_count % 4) == 0) { //0 or 3
|
||||
viterbi_butterfly2_generic(&depunctured[in_count & 0xfffffffc], d_metric0_generic, d_metric1_generic,
|
||||
d_path0_generic, d_path1_generic);
|
||||
if ((in_count % 4) == 0) { // 0 or 3
|
||||
viterbi_butterfly2_generic(&depunctured[in_count & 0xfffffffc],
|
||||
d_metric0_generic,
|
||||
d_metric1_generic,
|
||||
d_path0_generic,
|
||||
d_path1_generic);
|
||||
|
||||
if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11
|
||||
unsigned char c;
|
||||
if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11
|
||||
unsigned char c;
|
||||
|
||||
viterbi_get_output_generic(d_metric0_generic, d_path0_generic, d_ntraceback, &c);
|
||||
viterbi_get_output_generic(
|
||||
d_metric0_generic, d_path0_generic, d_ntraceback, &c);
|
||||
|
||||
if (out_count >= d_ntraceback) {
|
||||
for (int i= 0; i < 8; i++) {
|
||||
d_decoded[(out_count - d_ntraceback) * 8 + i] = (c >> (7 - i)) & 0x1;
|
||||
n_decoded++;
|
||||
}
|
||||
}
|
||||
out_count++;
|
||||
}
|
||||
}
|
||||
in_count++;
|
||||
}
|
||||
if (out_count >= d_ntraceback) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
d_decoded[(out_count - d_ntraceback) * 8 + i] =
|
||||
(c >> (7 - i)) & 0x1;
|
||||
n_decoded++;
|
||||
}
|
||||
}
|
||||
out_count++;
|
||||
}
|
||||
}
|
||||
in_count++;
|
||||
}
|
||||
|
||||
return d_decoded;
|
||||
return d_decoded;
|
||||
}
|
||||
|
||||
void
|
||||
viterbi_decoder::reset() {
|
||||
void viterbi_decoder::reset()
|
||||
{
|
||||
|
||||
viterbi_chunks_init_generic();
|
||||
viterbi_chunks_init_generic();
|
||||
|
||||
switch(d_ofdm->encoding) {
|
||||
case BPSK_1_2:
|
||||
case QPSK_1_2:
|
||||
case QAM16_1_2:
|
||||
d_ntraceback = 5;
|
||||
d_depuncture_pattern = PUNCTURE_1_2;
|
||||
d_k = 1;
|
||||
break;
|
||||
case QAM64_2_3:
|
||||
d_ntraceback = 9;
|
||||
d_depuncture_pattern = PUNCTURE_2_3;
|
||||
d_k = 2;
|
||||
break;
|
||||
case BPSK_3_4:
|
||||
case QPSK_3_4:
|
||||
case QAM16_3_4:
|
||||
case QAM64_3_4:
|
||||
d_ntraceback = 10;
|
||||
d_depuncture_pattern = PUNCTURE_3_4;
|
||||
d_k = 3;
|
||||
break;
|
||||
}
|
||||
switch (d_ofdm->encoding) {
|
||||
case BPSK_1_2:
|
||||
case QPSK_1_2:
|
||||
case QAM16_1_2:
|
||||
d_ntraceback = 5;
|
||||
d_depuncture_pattern = PUNCTURE_1_2;
|
||||
d_k = 1;
|
||||
break;
|
||||
case QAM64_2_3:
|
||||
d_ntraceback = 9;
|
||||
d_depuncture_pattern = PUNCTURE_2_3;
|
||||
d_k = 2;
|
||||
break;
|
||||
case BPSK_3_4:
|
||||
case QPSK_3_4:
|
||||
case QAM16_3_4:
|
||||
case QAM64_3_4:
|
||||
d_ntraceback = 10;
|
||||
d_depuncture_pattern = PUNCTURE_3_4;
|
||||
d_k = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize starting metrics to prefer 0 state
|
||||
void
|
||||
viterbi_decoder::viterbi_chunks_init_generic() {
|
||||
int i, j;
|
||||
void viterbi_decoder::viterbi_chunks_init_generic()
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
d_metric0_generic[i] = 0;
|
||||
d_path0_generic[i] = 0;
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
d_metric0_generic[i] = 0;
|
||||
d_path0_generic[i] = 0;
|
||||
}
|
||||
|
||||
int polys[2] = { 0x6d, 0x4f };
|
||||
for(i=0; i < 32; i++) {
|
||||
d_branchtab27_generic[0].c[i] = (polys[0] < 0) ^ PARTAB[(2*i) & abs(polys[0])] ? 1 : 0;
|
||||
d_branchtab27_generic[1].c[i] = (polys[1] < 0) ^ PARTAB[(2*i) & abs(polys[1])] ? 1 : 0;
|
||||
}
|
||||
int polys[2] = { 0x6d, 0x4f };
|
||||
for (i = 0; i < 32; i++) {
|
||||
d_branchtab27_generic[0].c[i] =
|
||||
(polys[0] < 0) ^ PARTAB[(2 * i) & abs(polys[0])] ? 1 : 0;
|
||||
d_branchtab27_generic[1].c[i] =
|
||||
(polys[1] < 0) ^ PARTAB[(2 * i) & abs(polys[1])] ? 1 : 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
d_mmresult[i] = 0;
|
||||
for (j = 0; j < TRACEBACK_MAX; j++) {
|
||||
d_ppresult[j][i] = 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 64; i++) {
|
||||
d_mmresult[i] = 0;
|
||||
for (j = 0; j < TRACEBACK_MAX; j++) {
|
||||
d_ppresult[j][i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,28 +30,30 @@ namespace ieee802_11 {
|
||||
class viterbi_decoder : public base
|
||||
{
|
||||
public:
|
||||
|
||||
virtual uint8_t* decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in);
|
||||
virtual uint8_t* decode(ofdm_param* ofdm, frame_param* frame, uint8_t* in);
|
||||
|
||||
private:
|
||||
union branchtab27 {
|
||||
unsigned char c[32];
|
||||
} d_branchtab27_generic[2];
|
||||
|
||||
union branchtab27 {
|
||||
unsigned char c[32];
|
||||
} d_branchtab27_generic[2];
|
||||
unsigned char d_metric0_generic[64] __attribute__((aligned(16)));
|
||||
unsigned char d_metric1_generic[64] __attribute__((aligned(16)));
|
||||
unsigned char d_path0_generic[64] __attribute__((aligned(16)));
|
||||
unsigned char d_path1_generic[64] __attribute__((aligned(16)));
|
||||
|
||||
unsigned char d_metric0_generic[64] __attribute__ ((aligned(16)));
|
||||
unsigned char d_metric1_generic[64] __attribute__ ((aligned(16)));
|
||||
unsigned char d_path0_generic[64] __attribute__ ((aligned(16)));
|
||||
unsigned char d_path1_generic[64] __attribute__ ((aligned(16)));
|
||||
void reset();
|
||||
|
||||
void reset();
|
||||
|
||||
void viterbi_chunks_init_generic();
|
||||
void viterbi_butterfly2_generic(unsigned char *symbols,
|
||||
unsigned char m0[], unsigned char m1[], unsigned char p0[],
|
||||
unsigned char p1[]);
|
||||
unsigned char viterbi_get_output_generic(unsigned char *mm0,
|
||||
unsigned char *pp0, int ntraceback, unsigned char *outbuf);
|
||||
void viterbi_chunks_init_generic();
|
||||
void viterbi_butterfly2_generic(unsigned char* symbols,
|
||||
unsigned char m0[],
|
||||
unsigned char m1[],
|
||||
unsigned char p0[],
|
||||
unsigned char p1[]);
|
||||
unsigned char viterbi_get_output_generic(unsigned char* mm0,
|
||||
unsigned char* pp0,
|
||||
int ntraceback,
|
||||
unsigned char* outbuf);
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
|
||||
@@ -56,280 +56,300 @@
|
||||
* would spill over into memory.
|
||||
*/
|
||||
|
||||
#define BUTTERFLY(i,sym) { \
|
||||
int m0,m1,m2,m3; \
|
||||
/* ACS for 0 branch */ \
|
||||
m0 = state[i].metric + mets[sym]; /* 2*i */ \
|
||||
m1 = state[i+32].metric + mets[3 ^ sym]; /* 2*i + 64 */ \
|
||||
if(m0 > m1){ \
|
||||
next[2*i].metric = m0; \
|
||||
next[2*i].path = state[i].path << 1; \
|
||||
} else { \
|
||||
next[2*i].metric = m1; \
|
||||
next[2*i].path = (state[i+32].path << 1)|1; \
|
||||
} \
|
||||
/* ACS for 1 branch */ \
|
||||
m2 = state[i].metric + mets[3 ^ sym]; /* 2*i + 1 */ \
|
||||
m3 = state[i+32].metric + mets[sym]; /* 2*i + 65 */ \
|
||||
if(m2 > m3){ \
|
||||
next[2*i+1].metric = m2; \
|
||||
next[2*i+1].path = state[i].path << 1; \
|
||||
} else { \
|
||||
next[2*i+1].metric = m3; \
|
||||
next[2*i+1].path = (state[i+32].path << 1)|1; \
|
||||
} \
|
||||
}
|
||||
#define BUTTERFLY(i, sym) \
|
||||
{ \
|
||||
int m0, m1, m2, m3; \
|
||||
/* ACS for 0 branch */ \
|
||||
m0 = state[i].metric + mets[sym]; /* 2*i */ \
|
||||
m1 = state[i + 32].metric + mets[3 ^ sym]; /* 2*i + 64 */ \
|
||||
if (m0 > m1) { \
|
||||
next[2 * i].metric = m0; \
|
||||
next[2 * i].path = state[i].path << 1; \
|
||||
} else { \
|
||||
next[2 * i].metric = m1; \
|
||||
next[2 * i].path = (state[i + 32].path << 1) | 1; \
|
||||
} \
|
||||
/* ACS for 1 branch */ \
|
||||
m2 = state[i].metric + mets[3 ^ sym]; /* 2*i + 1 */ \
|
||||
m3 = state[i + 32].metric + mets[sym]; /* 2*i + 65 */ \
|
||||
if (m2 > m3) { \
|
||||
next[2 * i + 1].metric = m2; \
|
||||
next[2 * i + 1].path = state[i].path << 1; \
|
||||
} else { \
|
||||
next[2 * i + 1].metric = m3; \
|
||||
next[2 * i + 1].path = (state[i + 32].path << 1) | 1; \
|
||||
} \
|
||||
}
|
||||
|
||||
using namespace gr::ieee802_11;
|
||||
|
||||
void
|
||||
viterbi_decoder::viterbi_butterfly2_sse2(unsigned char *symbols,
|
||||
__m128i *mm0, __m128i *mm1, __m128i *pp0, __m128i *pp1) {
|
||||
int i;
|
||||
void viterbi_decoder::viterbi_butterfly2_sse2(
|
||||
unsigned char* symbols, __m128i* mm0, __m128i* mm1, __m128i* pp0, __m128i* pp1)
|
||||
{
|
||||
int i;
|
||||
|
||||
__m128i *metric0, *metric1;
|
||||
__m128i *path0, *path1;
|
||||
__m128i *metric0, *metric1;
|
||||
__m128i *path0, *path1;
|
||||
|
||||
metric0 = mm0;
|
||||
path0 = pp0;
|
||||
metric1 = mm1;
|
||||
path1 = pp1;
|
||||
metric0 = mm0;
|
||||
path0 = pp0;
|
||||
metric1 = mm1;
|
||||
path1 = pp1;
|
||||
|
||||
// Operate on 4 symbols (2 bits) at a time
|
||||
// Operate on 4 symbols (2 bits) at a time
|
||||
|
||||
__m128i m0, m1, m2, m3, decision0, decision1, survivor0, survivor1;
|
||||
__m128i metsv, metsvm;
|
||||
__m128i shift0, shift1;
|
||||
__m128i tmp0, tmp1;
|
||||
__m128i sym0v, sym1v;
|
||||
__m128i m0, m1, m2, m3, decision0, decision1, survivor0, survivor1;
|
||||
__m128i metsv, metsvm;
|
||||
__m128i shift0, shift1;
|
||||
__m128i tmp0, tmp1;
|
||||
__m128i sym0v, sym1v;
|
||||
|
||||
sym0v = _mm_set1_epi8(symbols[0]);
|
||||
sym1v = _mm_set1_epi8(symbols[1]);
|
||||
sym0v = _mm_set1_epi8(symbols[0]);
|
||||
sym1v = _mm_set1_epi8(symbols[1]);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (symbols[0] == 2) {
|
||||
metsvm = _mm_xor_si128(d_branchtab27_sse2[1].v[i],sym1v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
|
||||
} else if (symbols[1] == 2) {
|
||||
metsvm = _mm_xor_si128(d_branchtab27_sse2[0].v[i],sym0v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
|
||||
} else {
|
||||
metsvm = _mm_add_epi8(_mm_xor_si128(d_branchtab27_sse2[0].v[i],sym0v),_mm_xor_si128(d_branchtab27_sse2[1].v[i],sym1v));
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(2),metsvm);
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (symbols[0] == 2) {
|
||||
metsvm = _mm_xor_si128(d_branchtab27_sse2[1].v[i], sym1v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1), metsvm);
|
||||
} else if (symbols[1] == 2) {
|
||||
metsvm = _mm_xor_si128(d_branchtab27_sse2[0].v[i], sym0v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1), metsvm);
|
||||
} else {
|
||||
metsvm = _mm_add_epi8(_mm_xor_si128(d_branchtab27_sse2[0].v[i], sym0v),
|
||||
_mm_xor_si128(d_branchtab27_sse2[1].v[i], sym1v));
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(2), metsvm);
|
||||
}
|
||||
|
||||
m0 = _mm_add_epi8(metric0[i], metsv);
|
||||
m1 = _mm_add_epi8(metric0[i+2], metsvm);
|
||||
m2 = _mm_add_epi8(metric0[i], metsvm);
|
||||
m3 = _mm_add_epi8(metric0[i+2], metsv);
|
||||
m0 = _mm_add_epi8(metric0[i], metsv);
|
||||
m1 = _mm_add_epi8(metric0[i + 2], metsvm);
|
||||
m2 = _mm_add_epi8(metric0[i], metsvm);
|
||||
m3 = _mm_add_epi8(metric0[i + 2], metsv);
|
||||
|
||||
decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0,m1),_mm_setzero_si128());
|
||||
decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2,m3),_mm_setzero_si128());
|
||||
survivor0 = _mm_or_si128(_mm_and_si128(decision0,m0),_mm_andnot_si128(decision0,m1));
|
||||
survivor1 = _mm_or_si128(_mm_and_si128(decision1,m2),_mm_andnot_si128(decision1,m3));
|
||||
decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0, m1), _mm_setzero_si128());
|
||||
decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2, m3), _mm_setzero_si128());
|
||||
survivor0 =
|
||||
_mm_or_si128(_mm_and_si128(decision0, m0), _mm_andnot_si128(decision0, m1));
|
||||
survivor1 =
|
||||
_mm_or_si128(_mm_and_si128(decision1, m2), _mm_andnot_si128(decision1, m3));
|
||||
|
||||
shift0 = _mm_slli_epi16(path0[i], 1);
|
||||
shift1 = _mm_slli_epi16(path0[2+i], 1);
|
||||
shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1));
|
||||
shift0 = _mm_slli_epi16(path0[i], 1);
|
||||
shift1 = _mm_slli_epi16(path0[2 + i], 1);
|
||||
shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1));
|
||||
|
||||
metric1[2*i] = _mm_unpacklo_epi8(survivor0,survivor1);
|
||||
tmp0 = _mm_or_si128(_mm_and_si128(decision0,shift0),_mm_andnot_si128(decision0,shift1));
|
||||
metric1[2 * i] = _mm_unpacklo_epi8(survivor0, survivor1);
|
||||
tmp0 = _mm_or_si128(_mm_and_si128(decision0, shift0),
|
||||
_mm_andnot_si128(decision0, shift1));
|
||||
|
||||
metric1[2*i+1] = _mm_unpackhi_epi8(survivor0,survivor1);
|
||||
tmp1 = _mm_or_si128(_mm_and_si128(decision1,shift0),_mm_andnot_si128(decision1,shift1));
|
||||
metric1[2 * i + 1] = _mm_unpackhi_epi8(survivor0, survivor1);
|
||||
tmp1 = _mm_or_si128(_mm_and_si128(decision1, shift0),
|
||||
_mm_andnot_si128(decision1, shift1));
|
||||
|
||||
path1[2*i] = _mm_unpacklo_epi8(tmp0, tmp1);
|
||||
path1[2*i+1] = _mm_unpackhi_epi8(tmp0, tmp1);
|
||||
}
|
||||
path1[2 * i] = _mm_unpacklo_epi8(tmp0, tmp1);
|
||||
path1[2 * i + 1] = _mm_unpackhi_epi8(tmp0, tmp1);
|
||||
}
|
||||
|
||||
metric0 = mm1;
|
||||
path0 = pp1;
|
||||
metric1 = mm0;
|
||||
path1 = pp0;
|
||||
metric0 = mm1;
|
||||
path0 = pp1;
|
||||
metric1 = mm0;
|
||||
path1 = pp0;
|
||||
|
||||
sym0v = _mm_set1_epi8(symbols[2]);
|
||||
sym1v = _mm_set1_epi8(symbols[3]);
|
||||
sym0v = _mm_set1_epi8(symbols[2]);
|
||||
sym1v = _mm_set1_epi8(symbols[3]);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (symbols[2] == 2) {
|
||||
metsvm = _mm_xor_si128(d_branchtab27_sse2[1].v[i],sym1v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (symbols[2] == 2) {
|
||||
metsvm = _mm_xor_si128(d_branchtab27_sse2[1].v[i], sym1v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1), metsvm);
|
||||
|
||||
} else if (symbols[3] == 2) {
|
||||
metsvm = _mm_xor_si128(d_branchtab27_sse2[0].v[i],sym0v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm);
|
||||
} else if (symbols[3] == 2) {
|
||||
metsvm = _mm_xor_si128(d_branchtab27_sse2[0].v[i], sym0v);
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(1), metsvm);
|
||||
|
||||
} else {
|
||||
metsvm = _mm_add_epi8(_mm_xor_si128(d_branchtab27_sse2[0].v[i],sym0v),_mm_xor_si128(d_branchtab27_sse2[1].v[i],sym1v));
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(2),metsvm);
|
||||
}
|
||||
} else {
|
||||
metsvm = _mm_add_epi8(_mm_xor_si128(d_branchtab27_sse2[0].v[i], sym0v),
|
||||
_mm_xor_si128(d_branchtab27_sse2[1].v[i], sym1v));
|
||||
metsv = _mm_sub_epi8(_mm_set1_epi8(2), metsvm);
|
||||
}
|
||||
|
||||
m0 = _mm_add_epi8(metric0[i], metsv);
|
||||
m1 = _mm_add_epi8(metric0[i+2], metsvm);
|
||||
m2 = _mm_add_epi8(metric0[i], metsvm);
|
||||
m3 = _mm_add_epi8(metric0[i+2], metsv);
|
||||
m0 = _mm_add_epi8(metric0[i], metsv);
|
||||
m1 = _mm_add_epi8(metric0[i + 2], metsvm);
|
||||
m2 = _mm_add_epi8(metric0[i], metsvm);
|
||||
m3 = _mm_add_epi8(metric0[i + 2], metsv);
|
||||
|
||||
decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0,m1),_mm_setzero_si128());
|
||||
decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2,m3),_mm_setzero_si128());
|
||||
survivor0 = _mm_or_si128(_mm_and_si128(decision0,m0),_mm_andnot_si128(decision0,m1));
|
||||
survivor1 = _mm_or_si128(_mm_and_si128(decision1,m2),_mm_andnot_si128(decision1,m3));
|
||||
decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0, m1), _mm_setzero_si128());
|
||||
decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2, m3), _mm_setzero_si128());
|
||||
survivor0 =
|
||||
_mm_or_si128(_mm_and_si128(decision0, m0), _mm_andnot_si128(decision0, m1));
|
||||
survivor1 =
|
||||
_mm_or_si128(_mm_and_si128(decision1, m2), _mm_andnot_si128(decision1, m3));
|
||||
|
||||
shift0 = _mm_slli_epi16(path0[i], 1);
|
||||
shift1 = _mm_slli_epi16(path0[2+i], 1);
|
||||
shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1));
|
||||
shift0 = _mm_slli_epi16(path0[i], 1);
|
||||
shift1 = _mm_slli_epi16(path0[2 + i], 1);
|
||||
shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1));
|
||||
|
||||
metric1[2*i] = _mm_unpacklo_epi8(survivor0,survivor1);
|
||||
tmp0 = _mm_or_si128(_mm_and_si128(decision0,shift0),_mm_andnot_si128(decision0,shift1));
|
||||
metric1[2 * i] = _mm_unpacklo_epi8(survivor0, survivor1);
|
||||
tmp0 = _mm_or_si128(_mm_and_si128(decision0, shift0),
|
||||
_mm_andnot_si128(decision0, shift1));
|
||||
|
||||
metric1[2*i+1] = _mm_unpackhi_epi8(survivor0,survivor1);
|
||||
tmp1 = _mm_or_si128(_mm_and_si128(decision1,shift0),_mm_andnot_si128(decision1,shift1));
|
||||
metric1[2 * i + 1] = _mm_unpackhi_epi8(survivor0, survivor1);
|
||||
tmp1 = _mm_or_si128(_mm_and_si128(decision1, shift0),
|
||||
_mm_andnot_si128(decision1, shift1));
|
||||
|
||||
path1[2*i] = _mm_unpacklo_epi8(tmp0, tmp1);
|
||||
path1[2*i+1] = _mm_unpackhi_epi8(tmp0, tmp1);
|
||||
}
|
||||
path1[2 * i] = _mm_unpacklo_epi8(tmp0, tmp1);
|
||||
path1[2 * i + 1] = _mm_unpackhi_epi8(tmp0, tmp1);
|
||||
}
|
||||
}
|
||||
|
||||
// Find current best path
|
||||
unsigned char
|
||||
viterbi_decoder::viterbi_get_output_sse2(__m128i *mm0, __m128i *pp0,
|
||||
int ntraceback, unsigned char *outbuf) {
|
||||
int i;
|
||||
int bestmetric, minmetric;
|
||||
int beststate = 0;
|
||||
int pos = 0;
|
||||
unsigned char viterbi_decoder::viterbi_get_output_sse2(__m128i* mm0,
|
||||
__m128i* pp0,
|
||||
int ntraceback,
|
||||
unsigned char* outbuf)
|
||||
{
|
||||
int i;
|
||||
int bestmetric, minmetric;
|
||||
int beststate = 0;
|
||||
int pos = 0;
|
||||
|
||||
// circular buffer with the last ntraceback paths
|
||||
d_store_pos = (d_store_pos + 1) % ntraceback;
|
||||
// circular buffer with the last ntraceback paths
|
||||
d_store_pos = (d_store_pos + 1) % ntraceback;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
_mm_store_si128((__m128i *) &d_mmresult[i*16], mm0[i]);
|
||||
_mm_store_si128((__m128i *) &d_ppresult[d_store_pos][i*16], pp0[i]);
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
_mm_store_si128((__m128i*)&d_mmresult[i * 16], mm0[i]);
|
||||
_mm_store_si128((__m128i*)&d_ppresult[d_store_pos][i * 16], pp0[i]);
|
||||
}
|
||||
|
||||
// Find out the best final state
|
||||
bestmetric = d_mmresult[beststate];
|
||||
minmetric = d_mmresult[beststate];
|
||||
// Find out the best final state
|
||||
bestmetric = d_mmresult[beststate];
|
||||
minmetric = d_mmresult[beststate];
|
||||
|
||||
for (i = 1; i < 64; i++) {
|
||||
if (d_mmresult[i] > bestmetric) {
|
||||
bestmetric = d_mmresult[i];
|
||||
beststate = i;
|
||||
}
|
||||
if (d_mmresult[i] < minmetric) {
|
||||
minmetric = d_mmresult[i];
|
||||
}
|
||||
}
|
||||
for (i = 1; i < 64; i++) {
|
||||
if (d_mmresult[i] > bestmetric) {
|
||||
bestmetric = d_mmresult[i];
|
||||
beststate = i;
|
||||
}
|
||||
if (d_mmresult[i] < minmetric) {
|
||||
minmetric = d_mmresult[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Trace back
|
||||
for (i = 0, pos = d_store_pos; i < (ntraceback - 1); i++) {
|
||||
// Obtain the state from the output bits
|
||||
// by clocking in the output bits in reverse order.
|
||||
// The state has only 6 bits
|
||||
beststate = d_ppresult[pos][beststate] >> 2;
|
||||
pos = (pos - 1 + ntraceback) % ntraceback;
|
||||
}
|
||||
// Trace back
|
||||
for (i = 0, pos = d_store_pos; i < (ntraceback - 1); i++) {
|
||||
// Obtain the state from the output bits
|
||||
// by clocking in the output bits in reverse order.
|
||||
// The state has only 6 bits
|
||||
beststate = d_ppresult[pos][beststate] >> 2;
|
||||
pos = (pos - 1 + ntraceback) % ntraceback;
|
||||
}
|
||||
|
||||
// Store output byte
|
||||
*outbuf = d_ppresult[pos][beststate];
|
||||
// Store output byte
|
||||
*outbuf = d_ppresult[pos][beststate];
|
||||
|
||||
// Zero out the path variable
|
||||
// and prevent metric overflow
|
||||
for (i = 0; i < 4; i++) {
|
||||
pp0[i] = _mm_setzero_si128();
|
||||
mm0[i] = _mm_sub_epi8(mm0[i], _mm_set1_epi8(minmetric));
|
||||
}
|
||||
// Zero out the path variable
|
||||
// and prevent metric overflow
|
||||
for (i = 0; i < 4; i++) {
|
||||
pp0[i] = _mm_setzero_si128();
|
||||
mm0[i] = _mm_sub_epi8(mm0[i], _mm_set1_epi8(minmetric));
|
||||
}
|
||||
|
||||
return bestmetric;
|
||||
return bestmetric;
|
||||
}
|
||||
|
||||
|
||||
uint8_t*
|
||||
viterbi_decoder::decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in) {
|
||||
uint8_t* viterbi_decoder::decode(ofdm_param* ofdm, frame_param* frame, uint8_t* in)
|
||||
{
|
||||
|
||||
d_ofdm = ofdm;
|
||||
d_frame = frame;
|
||||
d_ofdm = ofdm;
|
||||
d_frame = frame;
|
||||
|
||||
reset();
|
||||
uint8_t *depunctured = depuncture(in);
|
||||
reset();
|
||||
uint8_t* depunctured = depuncture(in);
|
||||
|
||||
int in_count = 0;
|
||||
int out_count = 0;
|
||||
int n_decoded = 0;
|
||||
int in_count = 0;
|
||||
int out_count = 0;
|
||||
int n_decoded = 0;
|
||||
|
||||
while(n_decoded < d_frame->n_data_bits) {
|
||||
while (n_decoded < d_frame->n_data_bits) {
|
||||
|
||||
if ((in_count % 4) == 0) { //0 or 3
|
||||
viterbi_butterfly2_sse2(&depunctured[in_count & 0xfffffffc], d_metric0, d_metric1, d_path0, d_path1);
|
||||
if ((in_count % 4) == 0) { // 0 or 3
|
||||
viterbi_butterfly2_sse2(&depunctured[in_count & 0xfffffffc],
|
||||
d_metric0,
|
||||
d_metric1,
|
||||
d_path0,
|
||||
d_path1);
|
||||
|
||||
if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11
|
||||
unsigned char c;
|
||||
if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11
|
||||
unsigned char c;
|
||||
|
||||
viterbi_get_output_sse2(d_metric0, d_path0, d_ntraceback, &c);
|
||||
viterbi_get_output_sse2(d_metric0, d_path0, d_ntraceback, &c);
|
||||
|
||||
if (out_count >= d_ntraceback) {
|
||||
for (int i= 0; i < 8; i++) {
|
||||
d_decoded[(out_count - d_ntraceback) * 8 + i] = (c >> (7 - i)) & 0x1;
|
||||
n_decoded++;
|
||||
}
|
||||
}
|
||||
out_count++;
|
||||
}
|
||||
}
|
||||
in_count++;
|
||||
}
|
||||
if (out_count >= d_ntraceback) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
d_decoded[(out_count - d_ntraceback) * 8 + i] =
|
||||
(c >> (7 - i)) & 0x1;
|
||||
n_decoded++;
|
||||
}
|
||||
}
|
||||
out_count++;
|
||||
}
|
||||
}
|
||||
in_count++;
|
||||
}
|
||||
|
||||
return d_decoded;
|
||||
return d_decoded;
|
||||
}
|
||||
|
||||
void
|
||||
viterbi_decoder::reset() {
|
||||
void viterbi_decoder::reset()
|
||||
{
|
||||
|
||||
viterbi_chunks_init_sse2();
|
||||
viterbi_chunks_init_sse2();
|
||||
|
||||
switch(d_ofdm->encoding) {
|
||||
case BPSK_1_2:
|
||||
case QPSK_1_2:
|
||||
case QAM16_1_2:
|
||||
d_ntraceback = 5;
|
||||
d_depuncture_pattern = PUNCTURE_1_2;
|
||||
d_k = 1;
|
||||
break;
|
||||
case QAM64_2_3:
|
||||
d_ntraceback = 9;
|
||||
d_depuncture_pattern = PUNCTURE_2_3;
|
||||
d_k = 2;
|
||||
break;
|
||||
case BPSK_3_4:
|
||||
case QPSK_3_4:
|
||||
case QAM16_3_4:
|
||||
case QAM64_3_4:
|
||||
d_ntraceback = 10;
|
||||
d_depuncture_pattern = PUNCTURE_3_4;
|
||||
d_k = 3;
|
||||
break;
|
||||
}
|
||||
switch (d_ofdm->encoding) {
|
||||
case BPSK_1_2:
|
||||
case QPSK_1_2:
|
||||
case QAM16_1_2:
|
||||
d_ntraceback = 5;
|
||||
d_depuncture_pattern = PUNCTURE_1_2;
|
||||
d_k = 1;
|
||||
break;
|
||||
case QAM64_2_3:
|
||||
d_ntraceback = 9;
|
||||
d_depuncture_pattern = PUNCTURE_2_3;
|
||||
d_k = 2;
|
||||
break;
|
||||
case BPSK_3_4:
|
||||
case QPSK_3_4:
|
||||
case QAM16_3_4:
|
||||
case QAM64_3_4:
|
||||
d_ntraceback = 10;
|
||||
d_depuncture_pattern = PUNCTURE_3_4;
|
||||
d_k = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize starting metrics to prefer 0 state
|
||||
void
|
||||
viterbi_decoder::viterbi_chunks_init_sse2() {
|
||||
int i, j;
|
||||
void viterbi_decoder::viterbi_chunks_init_sse2()
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
d_metric0[i] = _mm_setzero_si128();
|
||||
d_path0[i] = _mm_setzero_si128();
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
d_metric0[i] = _mm_setzero_si128();
|
||||
d_path0[i] = _mm_setzero_si128();
|
||||
}
|
||||
|
||||
int polys[2] = { 0x6d, 0x4f };
|
||||
for(i=0; i < 32; i++) {
|
||||
d_branchtab27_sse2[0].c[i] = (polys[0] < 0) ^ PARTAB[(2*i) & abs(polys[0])] ? 1 : 0;
|
||||
d_branchtab27_sse2[1].c[i] = (polys[1] < 0) ^ PARTAB[(2*i) & abs(polys[1])] ? 1 : 0;
|
||||
}
|
||||
int polys[2] = { 0x6d, 0x4f };
|
||||
for (i = 0; i < 32; i++) {
|
||||
d_branchtab27_sse2[0].c[i] =
|
||||
(polys[0] < 0) ^ PARTAB[(2 * i) & abs(polys[0])] ? 1 : 0;
|
||||
d_branchtab27_sse2[1].c[i] =
|
||||
(polys[1] < 0) ^ PARTAB[(2 * i) & abs(polys[1])] ? 1 : 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
d_mmresult[i] = 0;
|
||||
for (j = 0; j < TRACEBACK_MAX; j++) {
|
||||
d_ppresult[j][i] = 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 64; i++) {
|
||||
d_mmresult[i] = 0;
|
||||
for (j = 0; j < TRACEBACK_MAX; j++) {
|
||||
d_ppresult[j][i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
#ifndef INCLUDED_IEEE802_11_VITERBI_DECODER_X86_H
|
||||
#define INCLUDED_IEEE802_11_VITERBI_DECODER_X86_H
|
||||
|
||||
#include <xmmintrin.h>
|
||||
#include "base.h"
|
||||
#include <xmmintrin.h>
|
||||
|
||||
namespace gr {
|
||||
namespace ieee802_11 {
|
||||
@@ -31,28 +31,28 @@ namespace ieee802_11 {
|
||||
class viterbi_decoder : public base
|
||||
{
|
||||
public:
|
||||
|
||||
virtual uint8_t* decode(ofdm_param *ofdm, frame_param *frame, uint8_t *in);
|
||||
virtual uint8_t* decode(ofdm_param* ofdm, frame_param* frame, uint8_t* in);
|
||||
|
||||
private:
|
||||
union branchtab27 {
|
||||
unsigned char c[32];
|
||||
__m128i v[2];
|
||||
} d_branchtab27_sse2[2];
|
||||
|
||||
union branchtab27 {
|
||||
unsigned char c[32];
|
||||
__m128i v[2];
|
||||
} d_branchtab27_sse2[2];
|
||||
__m128i d_metric0[4] __attribute__((aligned(16)));
|
||||
__m128i d_metric1[4] __attribute__((aligned(16)));
|
||||
__m128i d_path0[4] __attribute__((aligned(16)));
|
||||
__m128i d_path1[4] __attribute__((aligned(16)));
|
||||
|
||||
__m128i d_metric0[4] __attribute__ ((aligned(16)));
|
||||
__m128i d_metric1[4] __attribute__ ((aligned(16)));
|
||||
__m128i d_path0[4] __attribute__ ((aligned(16)));
|
||||
__m128i d_path1[4] __attribute__ ((aligned(16)));
|
||||
virtual void reset();
|
||||
|
||||
virtual void reset();
|
||||
|
||||
void viterbi_chunks_init_sse2();
|
||||
void viterbi_butterfly2_sse2(unsigned char *symbols,
|
||||
__m128i m0[], __m128i m1[], __m128i p0[], __m128i p1[]);
|
||||
unsigned char viterbi_get_output_sse2(__m128i *mm0,
|
||||
__m128i *pp0, int ntraceback, unsigned char *outbuf);
|
||||
void viterbi_chunks_init_sse2();
|
||||
void viterbi_butterfly2_sse2(
|
||||
unsigned char* symbols, __m128i m0[], __m128i m1[], __m128i p0[], __m128i p1[]);
|
||||
unsigned char viterbi_get_output_sse2(__m128i* mm0,
|
||||
__m128i* pp0,
|
||||
int ntraceback,
|
||||
unsigned char* outbuf);
|
||||
};
|
||||
|
||||
} // namespace ieee802_11
|
||||
|
||||
Reference in New Issue
Block a user