mirror of https://github.com/PentHertz/srsLTE.git
Integrated LUT rate recovery in dlsch decoding. All tests ok
This commit is contained in:
parent
7e182e2eac
commit
3f3e045511
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue