Integrated LUT rate recovery in dlsch decoding. All tests ok

This commit is contained in:
ismagom 2015-09-22 21:20:36 +01:00
parent 7e182e2eac
commit 3f3e045511
18 changed files with 319 additions and 329 deletions

View File

@ -1,7 +1,7 @@
enbConfig=struct('NCellID',1,'CyclicPrefix','Normal','CellRefP',1);
pdschConfig=struct('Modulation','QPSK','RV',0,'TxScheme','Port0');
addpath('/home/ismael/work/srsLTE/debug/srslte/lib/phch/test')
addpath('/home/ismael/work/srsLTE/build/srslte/lib/phch/test')
TBs=40:8:800;
e_bits=1000;

View File

@ -41,6 +41,8 @@
uint32_t C;
uint32_t K1;
uint32_t K2;
uint32_t K1_idx;
uint32_t K2_idx;
uint32_t C1;
uint32_t C2;
uint32_t tbs;

View File

@ -78,10 +78,10 @@ SRSLTE_API int srslte_rm_turbo_rx(float *w_buff,
uint32_t nof_filler_bits);
SRSLTE_API int srslte_rm_turbo_rx_lut(float *input,
float *output,
uint32_t in_len,
float *output,
uint32_t out_len,
uint32_t rv_idx, uint32_t cb_idx);
uint32_t cb_idx,
uint32_t rv_idx);
/* High-level API */
typedef struct SRSLTE_API {

View File

@ -42,16 +42,16 @@
typedef struct SRSLTE_API {
uint32_t max_cb;
uint32_t buff_size;
float **buffer_f;
} srslte_softbuffer_rx_t;
typedef struct SRSLTE_API {
uint32_t max_cb;
uint32_t buff_size;
uint8_t **buffer_b;
} srslte_softbuffer_tx_t;
#define SOFTBUFFER_SIZE 18600
SRSLTE_API int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t * q,
uint32_t nof_prb);

View File

@ -65,7 +65,7 @@ typedef struct SRSLTE_API {
/* buffers */
uint8_t *cb_in;
void *cb_out;
uint8_t *parity_bits;
void *e;
uint8_t *temp_g_bits;
uint32_t *ul_interleaver;

View File

@ -46,7 +46,7 @@
#include <sys/time.h>
SRSLTE_API void get_time_interval(struct timeval * tdata);
#define SRSLTE_DEBUG_ENABLED 0
#define SRSLTE_DEBUG_ENABLED 1
SRSLTE_API extern int srslte_verbose;

View File

@ -75,16 +75,19 @@ int srslte_cbsegm(srslte_cbsegm_t *s, uint32_t tbs) {
ret = srslte_cbsegm_cbsize(idx1);
if (ret != SRSLTE_ERROR) {
s->K1 = (uint32_t) ret;
s->K1_idx = idx1;
if (idx1 > 0) {
ret = srslte_cbsegm_cbsize(idx1 - 1);
}
if (ret != SRSLTE_ERROR) {
if (s->C == 1) {
s->K2 = 0;
s->K2_idx = 0;
s->C2 = 0;
s->C1 = 1;
} else {
s->K2 = (uint32_t) ret;
s->K2_idx = idx1-1;
s->C2 = (s->C * s->K1 - Bp) / (s->K1 - s->K2);
s->C1 = s->C - s->C2;
}

View File

@ -38,7 +38,6 @@
#include "srslte/fec/cbsegm.h"
#define NCOLS 32
#define NROWS_MAX NCOLS
@ -47,10 +46,11 @@ static uint8_t RM_PERM_TC[NCOLS] = { 0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26,
static uint32_t interleaver_systematic_bits[SRSLTE_NOF_TC_CB_SIZES][6148]; // 4 tail bits
static uint32_t interleaver_parity_bits[SRSLTE_NOF_TC_CB_SIZES][2*6148];
static uint32_t deinterleaver[SRSLTE_NOF_TC_CB_SIZES][4][3*6148];
static uint32_t k0_vec[SRSLTE_NOF_TC_CB_SIZES][4][2];
static bool rm_turbo_tables_generated = false;
uint32_t table_buffer[6144], table_output[6144];
static uint32_t temp_table1[3*6176], temp_table2[3*6176];
void srslte_rm_turbo_gentable_systematic(uint32_t *table_bits, uint32_t k0_vec[4][2], uint32_t nrows, int ndummy) {
@ -122,6 +122,83 @@ void srslte_rm_turbo_gentable_parity(uint32_t *table_parity, uint32_t k0_vec[4][
}
void srslte_rm_turbo_gentable_receive(uint32_t *table, uint32_t cb_len, uint32_t rv_idx)
{
int nrows = (uint32_t) (cb_len / 3 - 1) / NCOLS + 1;
int ndummy = nrows*NCOLS - cb_len / 3;
if (ndummy < 0) {
ndummy = 0;
}
/* Undo bit collection. Account for dummy bits */
int N_cb = 3*nrows*NCOLS;
int k0 = nrows*(2*(uint32_t) ceilf((float) N_cb/(float) (8*nrows))*rv_idx+2);
int kidx;
int K_p = nrows * NCOLS;
int k = 0, jp=0, j=0;
bool isdummy = false;
int d_i, d_j;
while (k < cb_len) {
jp = (k0 + j) % N_cb;
if (jp < K_p || !(jp % 2)) {
if (jp >= K_p) {
d_i = ((jp - K_p) / 2) / nrows;
d_j = ((jp - K_p) / 2) % nrows;
} else {
d_i = jp / nrows;
d_j = jp % nrows;
}
if (d_j * NCOLS + RM_PERM_TC[d_i] >= ndummy) {
isdummy = false;
if (d_j * NCOLS + RM_PERM_TC[d_i] - ndummy < 0) {
isdummy = true;
}
} else {
isdummy = true;
}
} else {
uint32_t jpp = (jp - K_p - 1) / 2;
kidx = (RM_PERM_TC[jpp / nrows] + NCOLS * (jpp % nrows) + 1) % K_p;
if ((kidx - ndummy) < 0) {
isdummy = true;
} else {
isdummy = false;
}
}
if (!isdummy) {
temp_table1[k] = jp%(3*nrows*NCOLS);
k++;
}
j++;
}
for (int i = 0; i < cb_len / 3; i++) {
d_i = (i + ndummy) / NCOLS;
d_j = (i + ndummy) % NCOLS;
for (j = 0; j < 3; j++) {
if (j != 2) {
kidx = K_p * j + (j + 1) * (RM_PERM_TC[d_j] * nrows + d_i);
} else {
k = (i + ndummy - 1) % K_p;
if (k < 0)
k += K_p;
kidx = (k / NCOLS + nrows * RM_PERM_TC[k % NCOLS]) % K_p;
kidx = 2 * kidx + K_p + 1;
}
temp_table2[kidx] = 3*i+j;
}
}
for (int i=0;i<cb_len;i++) {
table[i] = temp_table2[temp_table1[i]];
}
}
void srslte_rm_turbo_gentables() {
if (!rm_turbo_tables_generated) {
rm_turbo_tables_generated = true;
@ -142,14 +219,19 @@ void srslte_rm_turbo_gentables() {
}
srslte_rm_turbo_gentable_systematic(interleaver_systematic_bits[cb_idx], k0_vec[cb_idx], nrows, ndummy);
srslte_rm_turbo_gentable_parity(interleaver_parity_bits[cb_idx], k0_vec[cb_idx], in_len/3, nrows, ndummy);
for (int i=0;i<4;i++) {
srslte_rm_turbo_gentable_receive(deinterleaver[cb_idx][i], in_len, i);
}
}
}
srslte_rm_turbo_gentable_receive(table_buffer, table_output, 132, 0);
}
int srslte_rm_turbo_tx_lut(uint8_t *w_buff, uint8_t *systematic, uint8_t *parity, uint8_t *output, uint32_t cb_idx, uint32_t out_len, uint32_t w_offset, uint32_t rv_idx) {
int srslte_rm_turbo_tx_lut(uint8_t *w_buff, uint8_t *systematic, uint8_t *parity, uint8_t *output,
uint32_t cb_idx, uint32_t out_len,
uint32_t w_offset, uint32_t rv_idx)
{
if (rv_idx < 4 && cb_idx < SRSLTE_NOF_TC_CB_SIZES) {
@ -189,6 +271,43 @@ int srslte_rm_turbo_tx_lut(uint8_t *w_buff, uint8_t *systematic, uint8_t *parity
return SRSLTE_ERROR_INVALID_INPUTS;
}
}
int srslte_rm_turbo_rx_lut(float *input, float *output, uint32_t in_len, uint32_t cb_idx, uint32_t rv_idx)
{
if (rv_idx < 4 && cb_idx < SRSLTE_NOF_TC_CB_SIZES) {
uint32_t out_len = 3*srslte_cbsegm_cbsize(cb_idx)+12;
uint32_t *deinter = deinterleaver[cb_idx][rv_idx];
for (int i=0;i<in_len;i++) {
output[deinter[i%out_len]] += input[i];
}
return 0;
} else {
printf("Invalid inputs rv_idx=%d, cb_idx=%d\n", rv_idx, cb_idx);
return SRSLTE_ERROR_INVALID_INPUTS;
}
}
/* Turbo Code Rate Matching.
@ -358,7 +477,7 @@ int srslte_rm_turbo_rx(float *w_buff, uint32_t w_buff_len, float *input, uint32_
} else if (input[k] != SRSLTE_RX_NULL) {
w_buff[jp] += input[k]; /* soft combine LLRs */
}
t k++;
k++;
}
j++;
}
@ -393,93 +512,6 @@ t k++;
void srslte_rm_turbo_gentable_receive(uint32_t *table_buffer, uint32_t *table_output, uint32_t cb_len, uint32_t rv_idx)
{
int nrows = (uint32_t) (cb_len / 3 - 1) / NCOLS + 1;
int ndummy = nrows*NCOLS - cb_len / 3;
if (ndummy < 0) {
ndummy = 0;
}
/* Undo bit collection. Account for dummy bits */
int N_cb = 3*nrows*NCOLS;
int k0 = nrows*(2*(uint32_t) ceilf((float) N_cb/(float) (8*nrows))*rv_idx+2);
printf("cb_len=%d, N_cb=%d, ndummy=%d, nrows=%d\n", cb_len, N_cb, ndummy, nrows);
int kidx;
int K_p = nrows * NCOLS;
int k = 0, jp=0, j=0;
bool isdummy = false;
int d_i, d_j;
while (k < cb_len) {
jp = (k0 + j) % N_cb;
if (jp < K_p || !(jp % 2)) {
if (jp >= K_p) {
d_i = ((jp - K_p) / 2) / nrows;
d_j = ((jp - K_p) / 2) % nrows;
} else {
d_i = jp / nrows;
d_j = jp % nrows;
}
if (d_j * NCOLS + RM_PERM_TC[d_i] >= ndummy) {
isdummy = false;
if (d_j * NCOLS + RM_PERM_TC[d_i] - ndummy < 0) {
isdummy = true;
}
} else {
isdummy = true;
}
} else {
uint32_t jpp = (jp - K_p - 1) / 2;
kidx = (RM_PERM_TC[jpp / nrows] + NCOLS * (jpp % nrows) + 1) % K_p;
if ((kidx - ndummy) < 0) {
isdummy = true;
} else {
isdummy = false;
}
}
if (!isdummy) {
table_buffer[k] = jp%(3*nrows*NCOLS);
k++;
}
j++;
}
for (int i = 0; i < cb_len / 3; i++) {
d_i = (i + ndummy) / NCOLS;
d_j = (i + ndummy) % NCOLS;
for (j = 0; j < 3; j++) {
if (j != 2) {
kidx = K_p * j + (j + 1) * (RM_PERM_TC[d_j] * nrows + d_i);
} else {
k = (i + ndummy - 1) % K_p;
if (k < 0)
k += K_p;
kidx = (k / NCOLS + nrows * RM_PERM_TC[k % NCOLS]) % K_p;
kidx = 2 * kidx + K_p + 1;
}
table_output[kidx] = 3*i+j;
}
}
}
int srslte_rm_turbo_rx_lut(float *input, uint32_t in_len, float *output, uint32_t out_len, uint32_t rv_idx, uint32_t cb_idx)
{
for (int i=0;i<in_len;i++) {
output[table_output[table_buffer[i%out_len]]] += input[i];
}
return 0;
}
/** High-level API */
int srslte_rm_turbo_initialize(srslte_rm_turbo_hl* h) {

View File

@ -63,9 +63,8 @@ int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t *q, uint32_t nof_prb) {
}
// FIXME: Use HARQ buffer limitation based on UE category
q->buff_size = 18600;
for (uint32_t i=0;i<q->max_cb;i++) {
q->buffer_f[i] = srslte_vec_malloc(sizeof(float) * q->buff_size);
q->buffer_f[i] = srslte_vec_malloc(sizeof(float) * SOFTBUFFER_SIZE);
if (!q->buffer_f[i]) {
perror("malloc");
return SRSLTE_ERROR;
@ -108,9 +107,7 @@ void srslte_softbuffer_rx_reset_cb(srslte_softbuffer_rx_t *q, uint32_t nof_cb) {
}
for (uint32_t i=0;i<nof_cb;i++) {
if (q->buffer_f[i]) {
for (uint32_t j=0;j<q->buff_size;j++) {
q->buffer_f[i][j] = SRSLTE_RX_NULL;
}
bzero(q->buffer_f[i], SOFTBUFFER_SIZE*sizeof(float));
}
}
}
@ -137,9 +134,8 @@ int srslte_softbuffer_tx_init(srslte_softbuffer_tx_t *q, uint32_t nof_prb) {
}
// FIXME: Use HARQ buffer limitation based on UE category
q->buff_size = 18600;
for (uint32_t i=0;i<q->max_cb;i++) {
q->buffer_b[i] = srslte_vec_malloc(sizeof(float) * q->buff_size);
q->buffer_b[i] = srslte_vec_malloc(sizeof(float) * SOFTBUFFER_SIZE);
if (!q->buffer_b[i]) {
perror("malloc");
return SRSLTE_ERROR;
@ -184,7 +180,7 @@ void srslte_softbuffer_tx_reset_cb(srslte_softbuffer_tx_t *q, uint32_t nof_cb) {
}
for (i=0;i<nof_cb;i++) {
if (q->buffer_b[i]) {
bzero(q->buffer_b[i], sizeof(uint8_t) * q->buff_size);
bzero(q->buffer_b[i], sizeof(uint8_t) * SOFTBUFFER_SIZE);
}
}
}

View File

@ -86,8 +86,6 @@ int srslte_tc_interl_LTE_gen(srslte_tc_interl_t *h, uint32_t long_cb) {
f1 = f1_list[cb_table_idx];
f2 = f2_list[cb_table_idx];
DEBUG("table_idx: %d, f1: %d, f2: %d\n", cb_table_idx, f1, f2);
h->forward[0] = 0;
h->reverse[0] = 0;
for (i = 1; i < long_cb; i++) {

View File

@ -33,10 +33,8 @@ TARGET_LINK_LIBRARIES(rm_turbo_test srslte)
ADD_TEST(rm_conv_test_1 rm_conv_test -t 480 -r 1920)
ADD_TEST(rm_conv_test_2 rm_conv_test -t 1920 -r 480)
ADD_TEST(rm_turbo_test_1 rm_turbo_test -t 480 -r 1920 -i 0)
ADD_TEST(rm_turbo_test_2 rm_turbo_test -t 1920 -r 480 -i 1)
ADD_TEST(rm_turbo_test_1 rm_turbo_test -t 480 -r 1920 -i 2)
ADD_TEST(rm_turbo_test_2 rm_turbo_test -t 1920 -r 480 -i 3)
ADD_TEST(rm_turbo_test_1 rm_turbo_test -e 1920)
ADD_TEST(rm_turbo_test_2 rm_turbo_test -e 8192)
BuildMex(MEXNAME rm_turbo_rx SOURCES rm_turbo_rx_mex.c LIBRARIES srslte srslte_mex)
@ -55,8 +53,7 @@ BuildMex(MEXNAME turbodecoder SOURCES turbodecoder_test_mex.c LIBRARIES srslte s
ADD_EXECUTABLE(turbocoder_test turbocoder_test.c)
TARGET_LINK_LIBRARIES(turbocoder_test srslte)
ADD_TEST(turbocoder_test_40 turbocoder_test -l 40)
ADD_TEST(turbocoder_test_6114 turbocoder_test -l 6114)
ADD_TEST(turbocoder_test_all turbocoder_test)
########################################################################
# Viterbi TEST

View File

@ -37,33 +37,34 @@
#include "srslte/srslte.h"
int nof_tx_bits = -1, nof_rx_bits = -1;
int nof_filler_bits = -1;
int rv_idx = 0;
int nof_e_bits = -1;
int rv_idx = -1;
int cb_idx = -1;
uint8_t systematic[6148], parity[2*6148];
uint8_t systematic_bytes[6148/8+1], parity_bytes[2*6148/8+1];
#define BUFFSZ 6176*3
uint8_t bits[3*6144+12];
uint8_t buff_b[BUFFSZ];
float buff_f[BUFFSZ];
float bits_f[3*6144+12];
float bits2_f[3*6144+12];
void usage(char *prog) {
printf("Usage: %s -t nof_tx_bits | -c cb_idx -r nof_rx_bits [-i rv_idx -f nof_filler_bits]\n", prog);
printf("Usage: %s -c cb_idx -e nof_e_bits [-i rv_idx]\n", prog);
}
void parse_args(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "tcrif")) != -1) {
while ((opt = getopt(argc, argv, "cei")) != -1) {
switch (opt) {
case 'f':
nof_filler_bits = atoi(argv[optind]);
break;
case 'c':
cb_idx = atoi(argv[optind]);
break;
case 't':
nof_tx_bits = atoi(argv[optind]);
break;
case 'r':
nof_rx_bits = atoi(argv[optind]);
case 'e':
nof_e_bits = atoi(argv[optind]);
break;
case 'i':
rv_idx = atoi(argv[optind]);
@ -73,178 +74,127 @@ void parse_args(int argc, char **argv) {
exit(-1);
}
}
if (nof_tx_bits == -1 && cb_idx == -1) {
usage(argv[0]);
exit(-1);
}
if (nof_rx_bits == -1) {
if (nof_e_bits == -1) {
usage(argv[0]);
exit(-1);
}
}
int main(int argc, char **argv) {
int i;
uint8_t *bits, *bits_out, *rm_bits, *rm_bits2, *rm_bits2_bytes, *w_buff_c;
float *rm_symbols, *unrm_symbols, *unrm_symbols2, *w_buff_f;
int nof_errors;
uint8_t *rm_bits, *rm_bits2, *rm_bits2_bytes;
float *rm_bits_f;
parse_args(argc, argv);
srslte_rm_turbo_gentables();
if (cb_idx != -1) {
nof_tx_bits = 3*srslte_cbsegm_cbsize(cb_idx)+12;
}
bits = malloc(sizeof(uint8_t) * nof_tx_bits);
if (!bits) {
rm_bits_f = malloc(sizeof(float) * nof_e_bits);
if (!rm_bits_f) {
perror("malloc");
exit(-1);
}
bits_out = malloc(sizeof(uint8_t) * nof_tx_bits);
if (!bits_out) {
perror("malloc");
exit(-1);
}
w_buff_c = malloc(sizeof(uint8_t) * nof_tx_bits * 10);
if (!w_buff_c) {
perror("malloc");
exit(-1);
}
rm_bits = malloc(sizeof(uint8_t) * nof_rx_bits);
rm_bits = malloc(sizeof(uint8_t) * nof_e_bits);
if (!rm_bits) {
perror("malloc");
exit(-1);
}
rm_bits2 = malloc(sizeof(uint8_t) * nof_rx_bits);
rm_bits2 = malloc(sizeof(uint8_t) * nof_e_bits);
if (!rm_bits2) {
perror("malloc");
exit(-1);
}
rm_bits2_bytes = malloc(sizeof(uint8_t) * nof_rx_bits/8 + 1);
rm_bits2_bytes = malloc(sizeof(uint8_t) * nof_e_bits/8 + 1);
if (!rm_bits2_bytes) {
perror("malloc");
exit(-1);
}
rm_symbols = malloc(sizeof(float) * nof_rx_bits);
if (!rm_symbols) {
perror("malloc");
exit(-1);
}
w_buff_f = malloc(sizeof(float) * nof_rx_bits * 10);
if (!w_buff_f) {
perror("malloc");
exit(-1);
}
unrm_symbols = malloc(sizeof(float) * nof_tx_bits);
if (!unrm_symbols) {
perror("malloc");
exit(-1);
}
unrm_symbols2 = malloc(sizeof(float) * nof_tx_bits);
if (!unrm_symbols2) {
perror("malloc");
exit(-1);
}
for (i = 0; i < nof_tx_bits; i++) {
bits[i] = rand() % 2;
uint32_t st=0, end=188;
if (cb_idx != -1) {
st=cb_idx;
end=cb_idx+1;
}
uint32_t rv_st=0, rv_end=4;
if (rv_idx != -1) {
rv_st=rv_idx;
rv_end=rv_idx+1;
}
for (i=0;i<nof_filler_bits;i++) {
bits[3*i+0] = SRSLTE_TX_NULL;
bits[3*i+1] = SRSLTE_TX_NULL;
}
bzero(w_buff_c, nof_tx_bits * 10 * sizeof(uint8_t));
bzero(w_buff_f, nof_rx_bits * 10 * sizeof(float));
srslte_rm_turbo_tx(w_buff_c, nof_tx_bits * 10, bits, nof_tx_bits, rm_bits, nof_rx_bits, 0);
for (cb_idx=st;cb_idx<end;cb_idx++) {
for (rv_idx=rv_st;rv_idx<rv_end;rv_idx++) {
uint32_t long_cb_enc = 3*srslte_cbsegm_cbsize(cb_idx)+12;
printf("checking cb_idx=%3d rv_idx=%d...", cb_idx, rv_idx);
for (i = 0; i < long_cb_enc; i++) {
bits[i] = rand() % 2;
}
bzero(buff_b, BUFFSZ * sizeof(uint8_t));
srslte_rm_turbo_tx(buff_b, BUFFSZ, bits, long_cb_enc, rm_bits, nof_e_bits, 0);
if (rv_idx > 0) {
srslte_rm_turbo_tx(w_buff_c, nof_tx_bits * 10, bits, nof_tx_bits, rm_bits, nof_rx_bits, rv_idx);
}
if (rv_idx > 0) {
srslte_rm_turbo_tx(buff_b, BUFFSZ, bits, long_cb_enc, rm_bits, nof_e_bits, rv_idx);
}
for (i=0;i<nof_filler_bits;i++) {
bits[3*i+0] = 0;
bits[3*i+1] = 0;
}
for (int i=0;i<nof_tx_bits/3;i++) {
systematic[i] = bits[3*i];
parity[i] = bits[3*i+1];
parity[i+nof_tx_bits/3] = bits[3*i+2];
}
srslte_bit_pack_vector(systematic, systematic_bytes, nof_tx_bits/3);
srslte_bit_pack_vector(parity, parity_bytes, 2*nof_tx_bits/3);
bzero(w_buff_c, nof_tx_bits * 10 * sizeof(uint8_t));
for (int i=0;i<long_cb_enc/3;i++) {
systematic[i] = bits[3*i];
parity[i] = bits[3*i+1];
parity[i+long_cb_enc/3] = bits[3*i+2];
}
srslte_bit_pack_vector(systematic, systematic_bytes, long_cb_enc/3);
srslte_bit_pack_vector(parity, parity_bytes, 2*long_cb_enc/3);
bzero(buff_b, BUFFSZ * sizeof(uint8_t));
bzero(rm_bits2_bytes, nof_rx_bits/8);
srslte_rm_turbo_tx_lut(w_buff_c, systematic_bytes, parity_bytes, rm_bits2_bytes, cb_idx, nof_rx_bits, 0, 0);
if (rv_idx > 0) {
bzero(rm_bits2_bytes, nof_rx_bits/8);
srslte_rm_turbo_tx_lut(w_buff_c, systematic_bytes, parity_bytes, rm_bits2_bytes, cb_idx, nof_rx_bits, 0, rv_idx);
}
bzero(rm_bits2_bytes, nof_e_bits/8);
srslte_rm_turbo_tx_lut(buff_b, systematic_bytes, parity_bytes, rm_bits2_bytes, cb_idx, nof_e_bits, 0, 0);
if (rv_idx > 0) {
bzero(rm_bits2_bytes, nof_e_bits/8);
srslte_rm_turbo_tx_lut(buff_b, systematic_bytes, parity_bytes, rm_bits2_bytes, cb_idx, nof_e_bits, 0, rv_idx);
}
srslte_bit_unpack_vector(rm_bits2_bytes, rm_bits2, nof_rx_bits);
for (i = 0; i < nof_rx_bits; i++) {
rm_symbols[i] = (float) rm_bits[i] ? 1 : -1;
}
for (int i=0;i<nof_rx_bits;i++) {
rm_symbols[i] = rand()%10-5;
}
srslte_bit_unpack_vector(rm_bits2_bytes, rm_bits2, nof_e_bits);
for (int i=0;i<nof_e_bits;i++) {
if (rm_bits2[i] != rm_bits[i]) {
printf("Error in TX bit %d\n", i);
exit(-1);
}
}
printf("OK TX...");
for (int i=0;i<nof_e_bits;i++) {
rm_bits_f[i] = rand()%10-5;
}
bzero(buff_f, BUFFSZ*sizeof(float));
srslte_rm_turbo_rx(buff_f, BUFFSZ, rm_bits_f, nof_e_bits, bits_f, long_cb_enc, rv_idx, 0);
bzero(bits2_f, long_cb_enc*sizeof(float));
srslte_rm_turbo_rx_lut(rm_bits_f, bits2_f, nof_e_bits, cb_idx, rv_idx);
for (int i=0;i<long_cb_enc;i++) {
if (bits_f[i] != bits2_f[i]) {
printf("error RX in bit %d %f!=%f\n", i, bits_f[i], bits2_f[i]);
exit(-1);
}
}
printf("OK RX\n");
bzero(w_buff_f, nof_rx_bits*10*sizeof(float));
struct timeval t[3];
gettimeofday(&t[1], NULL);
srslte_rm_turbo_rx(w_buff_f, nof_rx_bits * 10, rm_symbols, nof_rx_bits, unrm_symbols, nof_tx_bits, rv_idx, 0);
gettimeofday(&t[2], NULL);
get_time_interval(t);
printf("Old=%d us\n", t[0].tv_usec);
bzero(unrm_symbols2, nof_tx_bits*sizeof(float));
gettimeofday(&t[1], NULL);
srslte_rm_turbo_rx_lut(rm_symbols, nof_rx_bits, unrm_symbols2, nof_tx_bits, rv_idx, cb_idx);
gettimeofday(&t[2], NULL);
get_time_interval(t);
printf("New=%d us\n", t[0].tv_usec);
for (int i=0;i<nof_tx_bits;i++) {
if (unrm_symbols[i] != unrm_symbols2[i]) {
printf("error in bit %d %f!=%f\n", i, unrm_symbols[i], unrm_symbols2[i]);
exit(-1);
}
}
printf("Ok\n");
exit(0);
for (i=0;i<nof_tx_bits;i++) {
bits_out[i] = unrm_symbols[i]>0?1:0;
}
nof_errors = 0;
for (i = 0; i < nof_tx_bits; i++) {
if (bits_out[i] != bits[i]) {
nof_errors++;
}
}
free(bits);
free(rm_bits);
free(rm_symbols);
free(unrm_symbols);
free(bits_out);
free(rm_bits2);
free(rm_bits2_bytes);
if (nof_errors) {
printf("nof_errors=%d\n", nof_errors);
exit(-1);
}
printf("Ok\n");
exit(0);
}

View File

@ -64,6 +64,7 @@ void parse_args(int argc, char **argv) {
uint8_t input_bytes[6144/8];
uint8_t input_bits[6144];
uint8_t parity[3*6144+12];
uint8_t parity_bits[3*6144+12];
uint8_t output_bits[3*6144+12];
uint8_t output_bits2[3*6144+12];
@ -99,24 +100,23 @@ int main(int argc, char **argv) {
}
srslte_tcod_encode(&tcod, input_bits, output_bits, long_cb);
srslte_tcod_encode_lut(&tcod, input_bytes, parity, long_cb);
srslte_tcod_encode_lut(&tcod, input_bytes, parity, len);
srslte_bit_unpack_vector(parity, parity_bits, 2*(long_cb+4));
for (int i=0;i<long_cb;i++) {
output_bits2[3*i] = input_bits[i];
output_bits2[3*i+1] = parity_bits[i];
output_bits2[3*i+2] = parity_bits[i+long_cb+4];
}
if (SRSLTE_VERBOSE_ISINFO()) {
printf("1st encoder\n");
srslte_vec_fprint_b(stdout, output_bits2, long_cb);
srslte_vec_fprint_b(stdout, output_bits, long_cb);
printf("2nd encoder\n");
srslte_vec_fprint_b(stdout, &output_bits2[long_cb], long_cb);
srslte_vec_fprint_b(stdout, &output_bits[long_cb], long_cb);
printf("tail\n");
srslte_vec_fprint_b(stdout, &output_bits2[2*long_cb], 12);
srslte_vec_fprint_b(stdout, &output_bits[2*long_cb], 12);
srslte_vec_fprint_b(stdout, output_bits2, 3*long_cb);
srslte_vec_fprint_b(stdout, output_bits, 3*long_cb);
printf("\n");
}
for (int i=0;i<2*long_cb+12;i++) {
if (output_bits2[i] != output_bits[i]) {
for (int i=0;i<2*long_cb;i++) {
if (output_bits2[long_cb+i] != output_bits[long_cb+i]) {
printf("error in bit %d, len=%d\n", i, len);
exit(-1);
}

View File

@ -26,23 +26,23 @@
ADD_EXECUTABLE(modem_test modem_test.c)
TARGET_LINK_LIBRARIES(modem_test srslte)
ADD_TEST(modem_bpsk modem_test -n 1020 -m 1)
ADD_TEST(modem_qpsk modem_test -n 1020 -m 2)
ADD_TEST(modem_qam16 modem_test -n 1020 -m 4)
ADD_TEST(modem_qam64 modem_test -n 1020 -m 6)
ADD_TEST(modem_bpsk modem_test -n 1024 -m 1)
ADD_TEST(modem_qpsk modem_test -n 1024 -m 2)
ADD_TEST(modem_qam16 modem_test -n 1024 -m 4)
ADD_TEST(modem_qam64 modem_test -n 1008 -m 6)
ADD_TEST(modem_bpsk_soft modem_test -n 1020 -m 1 -s)
ADD_TEST(modem_qpsk_soft modem_test -n 1020 -m 2 -s)
ADD_TEST(modem_qam16_soft modem_test -n 1020 -m 4 -s)
ADD_TEST(modem_qam64_soft modem_test -n 1020 -m 6 -s)
ADD_TEST(modem_bpsk_soft modem_test -n 1024 -m 1 -s)
ADD_TEST(modem_qpsk_soft modem_test -n 1024 -m 2 -s)
ADD_TEST(modem_qam16_soft modem_test -n 1024 -m 4 -s)
ADD_TEST(modem_qam64_soft modem_test -n 1008 -m 6 -s)
ADD_EXECUTABLE(soft_demod_test soft_demod_test.c)
TARGET_LINK_LIBRARIES(soft_demod_test srslte)
ADD_TEST(modem_bpsk_soft_approx soft_demod_test -n 1020 -m 1)
ADD_TEST(modem_qpsk_soft_approx soft_demod_test -n 1020 -m 2)
ADD_TEST(modem_qam16_soft_approx soft_demod_test -n 1020 -m 4)
ADD_TEST(modem_qam64_soft_approx soft_demod_test -n 1020 -m 6)
ADD_TEST(modem_bpsk_soft_approx soft_demod_test -n 1024 -m 1)
ADD_TEST(modem_qpsk_soft_approx soft_demod_test -n 1024 -m 2)
ADD_TEST(modem_qam16_soft_approx soft_demod_test -n 1024 -m 4)
ADD_TEST(modem_qam64_soft_approx soft_demod_test -n 1008 -m 6)

View File

@ -222,6 +222,7 @@ int srslte_pdsch_init(srslte_pdsch_t *q, srslte_cell_t cell) {
if (srslte_modem_table_lte(&q->mod[i], modulations[i], true)) {
goto clean;
}
srslte_modem_table_bytes(&q->mod[i]);
}
srslte_sch_init(&q->dl_sch);
@ -509,14 +510,14 @@ int srslte_pdsch_encode_rnti(srslte_pdsch_t *q,
if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) {
return SRSLTE_ERROR;
}
srslte_scrambling_b_offset(&seq, (uint8_t*) q->e, 0, cfg->nbits.nof_bits);
srslte_scrambling_bytes_offset(&seq, (uint8_t*) q->e, 0, cfg->nbits.nof_bits);
srslte_sequence_free(&seq);
} else {
srslte_scrambling_b_offset(&q->seq[cfg->sf_idx], (uint8_t*) q->e, 0, cfg->nbits.nof_bits);
srslte_scrambling_bytes_offset(&q->seq[cfg->sf_idx], (uint8_t*) q->e, 0, cfg->nbits.nof_bits);
}
srslte_mod_modulate(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->e, q->d, cfg->nbits.nof_bits);
srslte_mod_modulate_bytes(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->e, q->d, cfg->nbits.nof_bits);
/* TODO: only diversity supported */
if (q->cell.nof_ports > 1) {
srslte_layermap_diversity(q->d, x, q->cell.nof_ports, cfg->nbits.nof_re);

View File

@ -109,13 +109,13 @@ int srslte_sch_init(srslte_sch_t *q) {
srslte_rm_turbo_gentables();
// Allocate floats for reception (LLRs)
q->cb_in = srslte_vec_malloc(sizeof(uint8_t) * SRSLTE_TCOD_MAX_LEN_CB+4);
q->cb_in = srslte_vec_malloc(sizeof(uint8_t) * (SRSLTE_TCOD_MAX_LEN_CB+8)/8);
if (!q->cb_in) {
goto clean;
}
q->cb_out = srslte_vec_malloc(sizeof(float) * (3 * SRSLTE_TCOD_MAX_LEN_CB + 12));
if (!q->cb_out) {
q->parity_bits = srslte_vec_malloc(sizeof(uint8_t) * (3 * SRSLTE_TCOD_MAX_LEN_CB + 16) / 8);
if (!q->parity_bits) {
goto clean;
}
q->temp_g_bits = srslte_vec_malloc(sizeof(uint8_t)*SRSLTE_MAX_PRB*12*12*12);
@ -144,8 +144,8 @@ void srslte_sch_free(srslte_sch_t *q) {
if (q->cb_in) {
free(q->cb_in);
}
if (q->cb_out) {
free(q->cb_out);
if (q->parity_bits) {
free(q->parity_bits);
}
if (q->temp_g_bits) {
free(q->temp_g_bits);
@ -173,7 +173,7 @@ uint32_t srslte_sch_last_noi(srslte_sch_t *q) {
*
*/
static int encode_tb_off(srslte_sch_t *q,
srslte_softbuffer_tx_t *soft_buffer, srslte_cbsegm_t *cb_segm,
srslte_softbuffer_tx_t *softbuffer, srslte_cbsegm_t *cb_segm,
uint32_t Qm, uint32_t rv, uint32_t nof_e_bits,
uint8_t *data, uint8_t *e_bits, uint32_t w_offset)
{
@ -186,14 +186,19 @@ static int encode_tb_off(srslte_sch_t *q,
if (q != NULL &&
e_bits != NULL &&
cb_segm != NULL &&
soft_buffer != NULL)
softbuffer != NULL)
{
if (cb_segm->F) {
fprintf(stderr, "Error filler bits are not supported. Use standard TBS\n");
return SRSLTE_ERROR;
}
if (cb_segm->C > softbuffer->max_cb) {
fprintf(stderr, "Error number of CB (%d) exceeds soft buffer size (%d CBs)\n", cb_segm->C, softbuffer->max_cb);
return -1;
}
uint32_t Gp = nof_e_bits / Qm;
uint32_t gamma = Gp;
@ -223,11 +228,14 @@ static int encode_tb_off(srslte_sch_t *q,
rp = 0;
for (i = 0; i < cb_segm->C; i++) {
uint32_t cblen_idx;
/* Get read lengths */
if (i < cb_segm->C2) {
cb_len = cb_segm->K2;
cblen_idx = cb_segm->K2_idx;
} else {
cb_len = cb_segm->K1;
cblen_idx = cb_segm->K1_idx;
}
if (cb_segm->C > 1) {
rlen = cb_len - 24;
@ -243,13 +251,6 @@ static int encode_tb_off(srslte_sch_t *q,
INFO("CB#%d: cb_len: %d, rlen: %d, wp: %d, rp: %d, E: %d\n", i,
cb_len, rlen, wp, rp, n_e);
int ret = srslte_cbsegm_cbindex(cb_len);
if (ret < 0) {
fprintf(stderr, "Error invalid CBLEN=%d\n", cb_len);
return -1;
}
uint8_t cblen_idx = (uint8_t) ret;
if (data) {
/* Copy data to another buffer, making space for the Codeblock CRC */
@ -276,26 +277,23 @@ static int encode_tb_off(srslte_sch_t *q,
}
/* Turbo Encoding */
srslte_tcod_encode_lut(&q->encoder, q->cb_in, (uint8_t*) q->cb_out, cblen_idx);
srslte_tcod_encode_lut(&q->encoder, q->cb_in, q->parity_bits, cblen_idx);
if (SRSLTE_VERBOSE_ISDEBUG()) {
DEBUG("CB#%d encoded: ", i);
srslte_vec_fprint_byte(stdout, q->cb_out, 2*cb_len/8);
srslte_vec_fprint_byte(stdout, q->parity_bits, 2*cb_len/8);
}
}
DEBUG("RM cblen_idx=%d, n_e=%d, wp=%d, nof_e_bits=%d\n",cblen_idx, n_e, wp, nof_e_bits);
/* Rate matching */
if (3*cb_len+12 < soft_buffer->buff_size) {
if (srslte_rm_turbo_tx_lut(soft_buffer->buffer_b[i], q->cb_in, (uint8_t*) q->cb_out, &e_bits[(wp+w_offset)/8], cblen_idx, n_e, (wp+w_offset)%8, rv))
{
fprintf(stderr, "Error in rate matching\n");
return SRSLTE_ERROR;
}
} else {
fprintf(stderr, "Encoded CB length exceeds RM buffer (%d>%d)\n",3*cb_len+12,soft_buffer->buff_size);
return SRSLTE_ERROR;
if (srslte_rm_turbo_tx_lut(softbuffer->buffer_b[i], q->cb_in, q->parity_bits,
&e_bits[(wp+w_offset)/8], cblen_idx, n_e, (wp+w_offset)%8, rv))
{
fprintf(stderr, "Error in rate matching\n");
return SRSLTE_ERROR;
}
/* Set read/write pointers */
rp += rlen;
wp += n_e;
@ -347,6 +345,16 @@ static int decode_tb(srslte_sch_t *q,
uint32_t Gp = nof_e_bits / Qm;
uint32_t gamma=Gp;
if (cb_segm->F) {
fprintf(stderr, "Error filler bits are not supported. Use standard TBS\n");
return SRSLTE_ERROR;
}
if (cb_segm->C > softbuffer->max_cb) {
fprintf(stderr, "Error number of CB (%d) exceeds soft buffer size (%d CBs)\n", cb_segm->C, softbuffer->max_cb);
return -1;
}
if (cb_segm->C>0) {
gamma = Gp%cb_segm->C;
}
@ -355,11 +363,15 @@ static int decode_tb(srslte_sch_t *q,
for (i = 0; i < cb_segm->C && early_stop; i++) {
/* Get read/write lengths */
uint32_t cblen_idx;
if (i < cb_segm->C2) {
cb_len = cb_segm->K2;
cblen_idx = cb_segm->K2_idx;
} else {
cb_len = cb_segm->K1;
cblen_idx = cb_segm->K1_idx;
}
if (cb_segm->C == 1) {
rlen = cb_len;
} else {
@ -381,16 +393,14 @@ static int decode_tb(srslte_sch_t *q,
cb_len, rlen - F, wp, rp, F, n_e);
/* Rate Unmatching */
if (srslte_rm_turbo_rx(softbuffer->buffer_f[i], softbuffer->buff_size,
&e_bits[rp], n_e,
(float*) q->cb_out, 3 * cb_len + 12, rv, F)) {
if (srslte_rm_turbo_rx_lut(&e_bits[rp], softbuffer->buffer_f[i], n_e, cblen_idx, rv)) {
fprintf(stderr, "Error in rate matching\n");
return SRSLTE_ERROR;
}
if (SRSLTE_VERBOSE_ISDEBUG()) {
DEBUG("CB#%d RMOUT: ", i);
srslte_vec_fprint_f(stdout, q->cb_out, 3*cb_len+12);
srslte_vec_fprint_f(stdout, softbuffer->buffer_f[i], 3*cb_len+12);
}
/* Turbo Decoding with CRC-based early stopping */
@ -403,7 +413,7 @@ static int decode_tb(srslte_sch_t *q,
srslte_tdec_reset(&q->decoder, cb_len);
do {
srslte_tdec_iteration(&q->decoder, (float*) q->cb_out, cb_len);
srslte_tdec_iteration(&q->decoder, softbuffer->buffer_f[i], cb_len);
q->nof_iterations++;
if (cb_segm->C > 1) {

View File

@ -94,9 +94,9 @@ ADD_EXECUTABLE(pdsch_test pdsch_test.c)
TARGET_LINK_LIBRARIES(pdsch_test srslte)
ADD_TEST(pdsch_test_bpsk pdsch_test -l 504 -m 1 -n 50 -r 2)
ADD_TEST(pdsch_test_qpsk pdsch_test -l 1000 -m 2 -n 50 -r 1)
ADD_TEST(pdsch_test_qam16 pdsch_test -l 50000 -m 4 -n 100)
ADD_TEST(pdsch_test_qam64 pdsch_test -l 61664 -m 6 -n 100 -r 0)
ADD_TEST(pdsch_test_qpsk pdsch_test -l 2216 -m 2 -n 50 -r 1)
ADD_TEST(pdsch_test_qam16 pdsch_test -l 18336 -m 4 -n 100)
ADD_TEST(pdsch_test_qam64 pdsch_test -l 75376 -m 6 -n 100 -r 0)
BuildMex(MEXNAME pdsch SOURCES pdsch_test_mex.c LIBRARIES srslte srslte_mex)
BuildMex(MEXNAME dlsch_encode SOURCES dlsch_encode_test_mex.c LIBRARIES srslte srslte_mex)

View File

@ -37,6 +37,7 @@
srslte_cell_t cell = {
6, // nof_prb
1, // nof_ports
0,
0, // cell_id
SRSLTE_CP_NORM, // cyclic prefix
SRSLTE_PHICH_SRSLTE_PHICH_R_1_6, // PHICH resources
@ -220,7 +221,7 @@ int main(int argc, char **argv) {
ce[i][j] = 1;
}
}
gettimeofday(&t[1], NULL);
int r = srslte_pdsch_decode(&pdsch, &pdsch_cfg, &softbuffer_rx, slot_symbols[0], ce, 0, data);
gettimeofday(&t[2], NULL);