mirror of https://github.com/pvnis/srsRAN_4G.git
Fixed B210 USRP Clock issue. Added Turbo Rate matching
parent
6fe5a05952
commit
eb52aeb1ab
@ -1,304 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "lte/fec/permute.h"
|
|
||||||
|
|
||||||
#include "lte/fec/turbodecoder.h"
|
|
||||||
|
|
||||||
|
|
||||||
void compute_beta(llr_t *beta, llr_t *data, llr_t *parity, int long_cb, int dec) {
|
|
||||||
llr_t m_b0, m_b1, m_b2, m_b3, m_b4, m_b5, m_b6, m_b7;
|
|
||||||
llr_t new0, new1, new2, new3, new4, new5, new6, new7;
|
|
||||||
llr_t old0, old1, old2, old3, old4, old5, old6, old7;
|
|
||||||
|
|
||||||
llr_t x, y, xy;
|
|
||||||
int k;
|
|
||||||
int end = long_cb + RATE;
|
|
||||||
|
|
||||||
old0 = beta[8 * (end) + 0];
|
|
||||||
old1 = beta[8 * (end) + 1];
|
|
||||||
old2 = beta[8 * (end) + 2];
|
|
||||||
old3 = beta[8 * (end) + 3];
|
|
||||||
old4 = beta[8 * (end) + 4];
|
|
||||||
old5 = beta[8 * (end) + 5];
|
|
||||||
old6 = beta[8 * (end) + 6];
|
|
||||||
old7 = beta[8 * (end) + 7];
|
|
||||||
|
|
||||||
for (k = end - 1; k >= 0; k--) {
|
|
||||||
if (k > long_cb - 1) {
|
|
||||||
if (dec == 1) {
|
|
||||||
x = data[RATE * (long_cb ) + NINPUTS * (k - long_cb)];
|
|
||||||
y = data[RATE * (long_cb ) + NINPUTS * (k - long_cb) + 1];
|
|
||||||
} else {
|
|
||||||
x = data[RATE * (long_cb ) + NINPUTS * RATE + NINPUTS * (k - long_cb)];
|
|
||||||
y = data[RATE * (long_cb ) + NINPUTS * RATE + NINPUTS * (k - long_cb) + 1];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
x = data[RATE * k];
|
|
||||||
y = parity[RATE * k];
|
|
||||||
}
|
|
||||||
xy = x + y;
|
|
||||||
|
|
||||||
m_b0 = old4 + xy;
|
|
||||||
m_b1 = old4;
|
|
||||||
m_b2 = old5 + y;
|
|
||||||
m_b3 = old5 + x;
|
|
||||||
m_b4 = old6 + x;
|
|
||||||
m_b5 = old6 + y;
|
|
||||||
m_b6 = old7;
|
|
||||||
m_b7 = old7 + xy;
|
|
||||||
|
|
||||||
new0 = old0;
|
|
||||||
new1 = old0 + xy;
|
|
||||||
new2 = old1 + x;
|
|
||||||
new3 = old1 + y;
|
|
||||||
new4 = old2 + y;
|
|
||||||
new5 = old2 + x;
|
|
||||||
new6 = old3 + xy;
|
|
||||||
new7 = old3;
|
|
||||||
|
|
||||||
if (m_b0 > new0) new0 = m_b0;
|
|
||||||
beta[8 * k + 0] = new0;
|
|
||||||
old0 = new0;
|
|
||||||
|
|
||||||
if (m_b1 > new1) new1 = m_b1;
|
|
||||||
beta[8 * k + 1] = new1;
|
|
||||||
old1 = new1;
|
|
||||||
|
|
||||||
if (m_b2 > new2) new2 = m_b2;
|
|
||||||
beta[8 * k + 2] = new2;
|
|
||||||
old2 = new2;
|
|
||||||
|
|
||||||
if (m_b3 > new3) new3 = m_b3;
|
|
||||||
beta[8 * k + 3] = new3;
|
|
||||||
old3 = new3;
|
|
||||||
|
|
||||||
if (m_b4 > new4) new4 = m_b4;
|
|
||||||
beta[8 * k + 4] = new4;
|
|
||||||
old4 = new4;
|
|
||||||
|
|
||||||
if (m_b5 > new5) new5 = m_b5;
|
|
||||||
beta[8 * k + 5] = new5;
|
|
||||||
old5 = new5;
|
|
||||||
|
|
||||||
if (m_b6 > new6) new6 = m_b6;
|
|
||||||
beta[8 * k + 6] = new6;
|
|
||||||
old6 = new6;
|
|
||||||
|
|
||||||
if (m_b7 > new7) new7 = m_b7;
|
|
||||||
beta[8 * k + 7] = new7;
|
|
||||||
old7 = new7;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void compute_alfa(llr_t *alfa, llr_t *beta, llr_t *data, llr_t *parity, llr_t *output, int long_cb, int dec) {
|
|
||||||
llr_t m_b0, m_b1, m_b2, m_b3, m_b4, m_b5, m_b6, m_b7;
|
|
||||||
llr_t new0, new1, new2, new3, new4, new5, new6, new7;
|
|
||||||
llr_t old0, old1, old2, old3, old4, old5, old6, old7;
|
|
||||||
llr_t max1_0, max1_1, max1_2, max1_3, max1_4, max1_5, max1_6, max1_7;
|
|
||||||
llr_t max0_0, max0_1, max0_2, max0_3, max0_4, max0_5, max0_6, max0_7;
|
|
||||||
llr_t m1, m0;
|
|
||||||
llr_t x, y, xy;
|
|
||||||
llr_t out;
|
|
||||||
int k;
|
|
||||||
int end = long_cb;
|
|
||||||
|
|
||||||
old0 = alfa[0];
|
|
||||||
old1 = alfa[1];
|
|
||||||
old2 = alfa[2];
|
|
||||||
old3 = alfa[3];
|
|
||||||
old4 = alfa[4];
|
|
||||||
old5 = alfa[5];
|
|
||||||
old6 = alfa[6];
|
|
||||||
old7 = alfa[7];
|
|
||||||
|
|
||||||
for (k = 1; k < end + 1; k++) {
|
|
||||||
x = data[RATE * (k - 1)];
|
|
||||||
y = parity[RATE * (k - 1)];
|
|
||||||
|
|
||||||
xy = x + y;
|
|
||||||
|
|
||||||
m_b0 = old0;
|
|
||||||
m_b1 = old3 + y;
|
|
||||||
m_b2 = old4 + y;
|
|
||||||
m_b3 = old7;
|
|
||||||
m_b4 = old1;
|
|
||||||
m_b5 = old2 + y;
|
|
||||||
m_b6 = old5 + y;
|
|
||||||
m_b7 = old6;
|
|
||||||
|
|
||||||
new0 = old1 + xy;
|
|
||||||
new1 = old2 + x;
|
|
||||||
new2 = old5 + x;
|
|
||||||
new3 = old6 + xy;
|
|
||||||
new4 = old0 + xy;
|
|
||||||
new5 = old3 + x;
|
|
||||||
new6 = old4 + x;
|
|
||||||
new7 = old7 + xy;
|
|
||||||
|
|
||||||
max0_0 = m_b0 + beta[8 * k + 0];
|
|
||||||
max0_1 = m_b1 + beta[8 * k + 1];
|
|
||||||
max0_2 = m_b2 + beta[8 * k + 2];
|
|
||||||
max0_3 = m_b3 + beta[8 * k + 3];
|
|
||||||
max0_4 = m_b4 + beta[8 * k + 4];
|
|
||||||
max0_5 = m_b5 + beta[8 * k + 5];
|
|
||||||
max0_6 = m_b6 + beta[8 * k + 6];
|
|
||||||
max0_7 = m_b7 + beta[8 * k + 7];
|
|
||||||
|
|
||||||
max1_0 = new0 + beta[8 * k + 0];
|
|
||||||
max1_1 = new1 + beta[8 * k + 1];
|
|
||||||
max1_2 = new2 + beta[8 * k + 2];
|
|
||||||
max1_3 = new3 + beta[8 * k + 3];
|
|
||||||
max1_4 = new4 + beta[8 * k + 4];
|
|
||||||
max1_5 = new5 + beta[8 * k + 5];
|
|
||||||
max1_6 = new6 + beta[8 * k + 6];
|
|
||||||
max1_7 = new7 + beta[8 * k + 7];
|
|
||||||
|
|
||||||
m1 = max1_0;
|
|
||||||
if (max1_1 > m1) m1 = max1_1;
|
|
||||||
if (max1_2 > m1) m1 = max1_2;
|
|
||||||
if (max1_3 > m1) m1 = max1_3;
|
|
||||||
if (max1_4 > m1) m1 = max1_4;
|
|
||||||
if (max1_5 > m1) m1 = max1_5;
|
|
||||||
if (max1_6 > m1) m1 = max1_6;
|
|
||||||
if (max1_7 > m1) m1 = max1_7;
|
|
||||||
|
|
||||||
m0 = max0_0;
|
|
||||||
if (max0_1 > m0) m0 = max0_1;
|
|
||||||
if (max0_2 > m0) m0 = max0_2;
|
|
||||||
if (max0_3 > m0) m0 = max0_3;
|
|
||||||
if (max0_4 > m0) m0 = max0_4;
|
|
||||||
if (max0_5 > m0) m0 = max0_5;
|
|
||||||
if (max0_6 > m0) m0 = max0_6;
|
|
||||||
if (max0_7 > m0) m0 = max0_7;
|
|
||||||
|
|
||||||
|
|
||||||
if (m_b0 > new0) new0 = m_b0;
|
|
||||||
old0 = new0;
|
|
||||||
|
|
||||||
if (m_b1 > new1) new1 = m_b1;
|
|
||||||
old1 = new1;
|
|
||||||
|
|
||||||
if (m_b2 > new2) new2 = m_b2;
|
|
||||||
old2 = new2;
|
|
||||||
|
|
||||||
if (m_b3 > new3) new3 = m_b3;
|
|
||||||
old3 = new3;
|
|
||||||
|
|
||||||
if (m_b4 > new4) new4 = m_b4;
|
|
||||||
old4 = new4;
|
|
||||||
|
|
||||||
if (m_b5 > new5) new5 = m_b5;
|
|
||||||
old5 = new5;
|
|
||||||
|
|
||||||
if (m_b6 > new6) new6 = m_b6;
|
|
||||||
old6 = new6;
|
|
||||||
|
|
||||||
if (m_b7 > new7) new7 = m_b7;
|
|
||||||
old7 = new7;
|
|
||||||
|
|
||||||
out = m1 - m0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (dec == 2) {
|
|
||||||
if (abs(out) < HALT_min) {
|
|
||||||
HALT_min = abs(out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
output[k - 1] = out;
|
|
||||||
}
|
|
||||||
|
|
||||||
alfa[0] = old0;
|
|
||||||
alfa[1] = old1;
|
|
||||||
alfa[2] = old2;
|
|
||||||
alfa[3] = old3;
|
|
||||||
alfa[4] = old4;
|
|
||||||
alfa[5] = old5;
|
|
||||||
alfa[6] = old6;
|
|
||||||
alfa[7] = old7;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DEC_RSC(tdec_t *q, llr_t *input, llr_t *output, int *per, int dec) {
|
|
||||||
int k;
|
|
||||||
int i;
|
|
||||||
int last_state = q->long_cb + RATE;
|
|
||||||
|
|
||||||
/** Initialize alfa states */
|
|
||||||
q->alfa[0] = 0;
|
|
||||||
for (k = 1; k < NUMSTATES; k++) {
|
|
||||||
q->alfa[k] = -INF;
|
|
||||||
}
|
|
||||||
|
|
||||||
q->beta[last_state * NUMSTATES] = 0;
|
|
||||||
for (k = 1; k < NUMSTATES; k++)
|
|
||||||
q->beta[last_state * NUMSTATES + k] = -INF;
|
|
||||||
|
|
||||||
/* copy data temporal buffer (to allow fastest loops)*/
|
|
||||||
memcpy(q->data, input, RATE * last_state * sizeof (llr_t));
|
|
||||||
|
|
||||||
q->parity = &input[dec];
|
|
||||||
|
|
||||||
if (dec == 1) {
|
|
||||||
for (i = 0; i < last_state; i++) {
|
|
||||||
q->data[RATE * i] += q->W[i ];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (i = 0; i < last_state; i++) {
|
|
||||||
q->data[RATE * i] = q->LLR1[per[i ]] - q->W[per[i ]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compute_beta(q->beta, q->data, &input[dec], q->long_cb, dec);
|
|
||||||
compute_alfa(q->alfa, q->beta, q->data, &input[dec], output, q->long_cb, dec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void decide(llr_t *LLR2, char *output, int *desper, int long_cb) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < long_cb; i++)
|
|
||||||
output[i] = (LLR2[desper[i]] > 0) ? 1 : 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_W(llr_t *W, llr_t *LLR1, llr_t *LLR2, int *desper, int long_cb) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < long_cb; i++) {
|
|
||||||
W[i] += LLR2[desper[i]] - LLR1[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int turbo_decoder(tdec_t *q, llr_t *input, char *output, int *halt) {
|
|
||||||
|
|
||||||
int i;
|
|
||||||
long halt_mean=0;
|
|
||||||
int stop=0;
|
|
||||||
q->iteration = 0;
|
|
||||||
|
|
||||||
|
|
||||||
if (ComputePermutation(&q->permuta, q->long_cb,PER_UMTS)<0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
memset(q->W, 0, sizeof (llr_t) * q->long_cb);
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (q->iteration)
|
|
||||||
update_W(q->W, q->LLR1, q->LLR2, q->permuta.DESPER, q->long_cb);
|
|
||||||
|
|
||||||
|
|
||||||
DEC_RSC(q, input, q->LLR1, q->permuta.PER, 1);
|
|
||||||
|
|
||||||
DEC_RSC(q, input, q->LLR2, q->permuta.PER, 2);
|
|
||||||
|
|
||||||
q->iteration++;
|
|
||||||
|
|
||||||
} while (q->iteration < q->max_iterations && stop==0);
|
|
||||||
decide(q->LLR2, output, q->permuta.DESPER, q->long_cb);
|
|
||||||
|
|
||||||
return q->iteration;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue