LUT TurboCoder working in matlab

master
ismagom 9 years ago
parent 4cd64b6de8
commit f04346ce97

@ -1,10 +1,10 @@
ueConfig=struct('NCellID',1,'NULRB',6,'RNTI',64,'CyclicPrefixUL','Normal','NTxAnts',1,'Shortened',0,'Hopping','Off','SeqGroup',0,'CyclicShift',0);
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',0,'Shortened',0,'DynCyclicShift',0);
addpath('../../debug/srslte/lib/phch/test')
addpath('../../build/srslte/lib/phch/test')
TBs=336;
cqilen=20;
cqilen=0;
rvs=0;
mods={'16QAM'};
betas=5;

@ -4,11 +4,11 @@ puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',0,'Shortened',0);
addpath('../../build/srslte/lib/phch/test')
TBs=336;
TBs=40;
cqilen=0;
mods={'16QAM'};
mods={'QPSK'};
rvs=0;
betas=5;
betas=0;
for i=1:length(TBs)
for m=1:length(mods)
@ -37,12 +37,12 @@ for i=1:length(TBs)
end
if (cqilen(c)>0 || TBs(i)>0)
[mat, info]=lteULSCH(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit,[]);
mat(mat==-2)=3;
mat(mat==-1)=2;
[lib]=srslte_ulsch_encode(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit);
lib(lib==192)=3;
lib(lib==48)=2;
[mat, info]=lteULSCH(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit,[]);
mat(mat==-2)=3;
mat(mat==-1)=2;
err=sum(abs(double(mat)-double(lib)));
if (err > 0)
disp(err)

@ -42,6 +42,7 @@
#include "srslte/config.h"
#include "srslte/fec/tc_interl.h"
#define SRSLTE_TCOD_MAX_LEN_CB_BYTES (6144/8)
#ifndef SRSLTE_TX_NULL
#define SRSLTE_TX_NULL 100
@ -53,6 +54,17 @@ typedef struct SRSLTE_API {
srslte_tc_interl_t interl;
} srslte_tcod_t;
/* This structure is used as an output for the LUT version of the encoder.
* The encoder produces parity bits only and rate matching will interleave them
* with the systematic bits
*/
typedef struct {
uint8_t parity1[SRSLTE_TCOD_MAX_LEN_CB_BYTES];
uint8_t parity2[SRSLTE_TCOD_MAX_LEN_CB_BYTES];
uint8_t tail[12]; // this bits are unpacked
} srslte_tcod_out_t;
SRSLTE_API int srslte_tcod_init(srslte_tcod_t *h,
uint32_t max_long_cb);
@ -65,7 +77,12 @@ SRSLTE_API int srslte_tcod_encode(srslte_tcod_t *h,
SRSLTE_API int srslte_tcod_encode_lut(srslte_tcod_t *h,
uint8_t *input,
uint8_t *output,
srslte_tcod_out_t *output,
uint32_t long_cb);
SRSLTE_API void srslte_tcod_output_to_array(uint8_t *input_bytes,
srslte_tcod_out_t *output,
uint8_t *array,
uint32_t long_cb);
SRSLTE_API void srslte_tcod_gentable();

@ -68,6 +68,7 @@ typedef struct SRSLTE_API {
uint8_t *cb_temp;
void *cb_out;
void *e;
srslte_tcod_out_t cb_tcod_out;
srslte_tcod_t encoder;
srslte_tdec_t decoder;

@ -33,6 +33,7 @@
#include <stdint.h>
#include "srslte/fec/rm_turbo.h"
#include "srslte/utils/bit.h"
#define NCOLS 32
#define NROWS_MAX NCOLS
@ -40,6 +41,7 @@
uint8_t RM_PERM_TC[NCOLS] = { 0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26,
6, 22, 14, 30, 1, 17, 9, 25, 5, 21, 13, 29, 3, 19, 11, 27, 7, 23, 15, 31 };
uint32_t test_interleaver[64*1024];
/* Turbo Code Rate Matching.
* 3GPP TS 36.212 v10.1.0 section 5.1.4.1
@ -53,6 +55,59 @@ uint8_t RM_PERM_TC[NCOLS] = { 0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26,
*
* TODO: Soft buffer size limitation according to UE category
*/
//#define new
#ifdef new
int srslte_rm_turbo_tx(uint8_t *w_buff, uint32_t w_buff_len, uint8_t *input, uint32_t in_len, uint8_t *output,
uint32_t out_len, uint32_t rv_idx) {
int ndummy, kidx;
int nrows, K_p;
int i, j, k, s, N_cb, k0;
if (in_len < 3) {
fprintf(stderr, "Error minimum input length for rate matching is 3\n");
return -1;
}
nrows = (uint32_t) (in_len / 3 - 1) / NCOLS + 1;
K_p = nrows * NCOLS;
if (3 * K_p > w_buff_len) {
fprintf(stderr,
"Input too large. Max input length including dummy bits is %d (3x%dx32, in_len %d, Kp=%d)\n",
w_buff_len, nrows, in_len, K_p);
return -1;
}
ndummy = K_p - in_len / 3;
if (ndummy < 0) {
ndummy = 0;
}
if (rv_idx == 0) {
srslte_bit_interleave(input, w_buff, test_interleaver, in_len);
}
/* Bit selection and transmission 5.1.4.1.2 */
N_cb = 3 * K_p; // TODO: Soft buffer size limitation
k0 = nrows
* (2 * (uint32_t) ceilf((float) N_cb / (float) (8 * nrows)) * rv_idx + 2);
k = 0;
j = 0;
while (k < out_len) {
if (w_buff[(k0 + j) % N_cb] != SRSLTE_TX_NULL) {
output[k] = w_buff[(k0 + j) % N_cb];
k++;
}
j++;
}
return 0;
}
#else
int srslte_rm_turbo_tx(uint8_t *w_buff, uint32_t w_buff_len, uint8_t *input, uint32_t in_len, uint8_t *output,
uint32_t out_len, uint32_t rv_idx) {
@ -129,6 +184,7 @@ int srslte_rm_turbo_tx(uint8_t *w_buff, uint32_t w_buff_len, uint8_t *input, uin
}
return 0;
}
#endif
/* Undoes Turbo Code Rate Matching.
* 3GPP TS 36.212 v10.1.0 section 5.1.4.1

@ -43,7 +43,9 @@
uint8_t tcod_lut_next_state[188][8][256];
uint8_t tcod_lut_output[188][8][256];
uint32_t tcod_per_fw[188][6114];
uint32_t tcod_per_fw[188][6144];
static bool table_initiated = false;
int srslte_tcod_init(srslte_tcod_t *h, uint32_t max_long_cb) {
@ -52,6 +54,11 @@ int srslte_tcod_init(srslte_tcod_t *h, uint32_t max_long_cb) {
}
h->max_long_cb = max_long_cb;
h->temp = srslte_vec_malloc(max_long_cb/8);
if (!table_initiated) {
table_initiated = true;
srslte_tcod_gentable();
}
return 0;
}
@ -177,7 +184,7 @@ int srslte_tcod_encode(srslte_tcod_t *h, uint8_t *input, uint8_t *output, uint32
}
/* Expects bytes and produces bytes. The systematic and parity bits are interlaced in the output */
int srslte_tcod_encode_lut(srslte_tcod_t *h, uint8_t *input, uint8_t *output, uint32_t long_cb)
int srslte_tcod_encode_lut(srslte_tcod_t *h, uint8_t *input, srslte_tcod_out_t *output, uint32_t long_cb)
{
if (long_cb % 8) {
fprintf(stderr, "Turbo coder LUT implementation long_cb must be multiple of 8\n");
@ -193,7 +200,7 @@ int srslte_tcod_encode_lut(srslte_tcod_t *h, uint8_t *input, uint8_t *output, ui
/* Parity bits for the 1st constituent encoders */
uint8_t state0 = 0;
for (uint32_t i=0;i<long_cb/8;i++) {
output[i] = tcod_lut_output[len_idx][state0][input[i]];
output->parity1[i] = tcod_lut_output[len_idx][state0][input[i]];
state0 = tcod_lut_next_state[len_idx][state0][input[i]] % 8;
}
@ -203,7 +210,7 @@ int srslte_tcod_encode_lut(srslte_tcod_t *h, uint8_t *input, uint8_t *output, ui
/* Parity bits for the 2nd constituent encoders */
uint8_t state1 = 0;
for (uint32_t i=0;i<long_cb/8;i++) {
output[long_cb/8+i] = tcod_lut_output[len_idx][state1][h->temp[i]];
output->parity2[i] = tcod_lut_output[len_idx][state1][h->temp[i]];
state1 = tcod_lut_next_state[len_idx][state1][h->temp[i]] % 8;
}
@ -211,7 +218,6 @@ int srslte_tcod_encode_lut(srslte_tcod_t *h, uint8_t *input, uint8_t *output, ui
uint8_t reg1_0, reg1_1, reg1_2, reg2_0, reg2_1, reg2_2;
uint8_t bit, in, out;
uint8_t k=0;
uint8_t tail[12];
reg2_0 = (state1&4)>>2;
reg2_1 = (state1&2)>>1;
@ -225,7 +231,7 @@ int srslte_tcod_encode_lut(srslte_tcod_t *h, uint8_t *input, uint8_t *output, ui
for (uint32_t j = 0; j < NOF_REGS; j++) {
bit = reg1_2 ^ reg1_1;
tail[k] = bit;
output->tail[k] = bit;
k++;
in = bit ^ (reg1_2 ^ reg1_1);
@ -235,7 +241,7 @@ int srslte_tcod_encode_lut(srslte_tcod_t *h, uint8_t *input, uint8_t *output, ui
reg1_1 = reg1_0;
reg1_0 = in;
tail[k] = out;
output->tail[k] = out;
k++;
}
@ -243,7 +249,7 @@ int srslte_tcod_encode_lut(srslte_tcod_t *h, uint8_t *input, uint8_t *output, ui
for (uint32_t j = 0; j < NOF_REGS; j++) {
bit = reg2_2 ^ reg2_1;
tail[k] = bit;
output->tail[k] = bit;
k++;
in = bit ^ (reg2_2 ^ reg2_1);
@ -253,15 +259,24 @@ int srslte_tcod_encode_lut(srslte_tcod_t *h, uint8_t *input, uint8_t *output, ui
reg2_1 = reg2_0;
reg2_0 = in;
tail[k] = out;
output->tail[k] = out;
k++;
}
srslte_bit_pack_vector(tail, &output[2*(long_cb/8)], TOTALTAIL);
return 2*long_cb+TOTALTAIL;
}
void srslte_tcod_output_to_array(uint8_t *input_bytes, srslte_tcod_out_t *output, uint8_t *array, uint32_t long_cb)
{
for (int i=0;i<long_cb;i++) {
array[3*i] = input_bytes[i/8] & (1<<(7-i%8))?1:0;
array[3*i+1] = output->parity1[i/8] & (1<<(7-i%8))?1:0;
array[3*i+2] = output->parity2[i/8] & (1<<(7-i%8))?1:0;
}
memcpy(&array[3*long_cb], output->tail, 12);
}
void srslte_tcod_gentable() {
srslte_tc_interl_t interl;

@ -64,9 +64,8 @@ void parse_args(int argc, char **argv) {
uint8_t input_bytes[6144/8];
uint8_t input_bits[6144];
uint8_t output_bits[3*6144+12];
uint8_t output_bytes[3*6144+12];
uint8_t output_bits2[3*6144+12];
uint8_t output_bits3[3*6144+12];
srslte_tcod_out_t tcod_output;
int main(int argc, char **argv) {
@ -100,35 +99,26 @@ int main(int argc, char **argv) {
}
srslte_tcod_encode(&tcod, input_bits, output_bits, long_cb);
srslte_tcod_encode_lut(&tcod, input_bytes, output_bytes, long_cb);
srslte_tcod_encode_lut(&tcod, input_bytes, &tcod_output, long_cb);
srslte_bit_unpack_vector(output_bytes, output_bits2, 2*long_cb+12);
/* de-Interleace bits for comparison */
for (int i=0;i<long_cb;i++) {
for (int j=0;j<2;j++) {
output_bits3[j*long_cb+i] = output_bits[3*i+j+1];
}
}
// copy tail
memcpy(&output_bits3[2*long_cb], &output_bits[3*long_cb], 12);
srslte_tcod_output_to_array(input_bytes, &tcod_output, output_bits2, long_cb);
if (SRSLTE_VERBOSE_ISINFO()) {
printf("1st encoder\n");
srslte_vec_fprint_b(stdout, output_bits2, long_cb);
srslte_vec_fprint_b(stdout, output_bits3, 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_bits3[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_bits3[2*long_cb], 12);
srslte_vec_fprint_b(stdout, &output_bits[2*long_cb], 12);
printf("\n");
}
for (int i=0;i<2*long_cb+12;i++) {
if (output_bits2[i] != output_bits3[i]) {
if (output_bits2[i] != output_bits[i]) {
printf("error in bit %d, len=%d\n", i, len);
exit(-1);
}

@ -259,21 +259,14 @@ static int encode_tb(srslte_sch_t *q,
srslte_crc_attach_byte(&q->crc_cb, q->cb_in, rlen);
}
/* pack bits to temporal buffer for encoding */
srslte_bit_unpack_vector(q->cb_in, q->cb_temp, cb_len);
/* Set the filler bits to <NULL> */
for (int j = 0; j < F; j++) {
q->cb_temp[j] = SRSLTE_TX_NULL;
}
if (SRSLTE_VERBOSE_ISDEBUG()) {
DEBUG("CB#%d: ", i);
srslte_vec_fprint_hex(stdout, q->cb_temp, cb_len);
srslte_vec_fprint_byte(stdout, q->cb_in, cb_len/8);
}
/* Turbo Encoding */
srslte_tcod_encode(&q->encoder, q->cb_temp, (uint8_t*) q->cb_out, cb_len);
srslte_tcod_encode_lut(&q->encoder, q->cb_in, &q->cb_tcod_out, cb_len);
srslte_tcod_output_to_array(q->cb_in, &q->cb_tcod_out, q->cb_out, cb_len);
if (SRSLTE_VERBOSE_ISDEBUG()) {
DEBUG("CB#%d encoded: ", i);
@ -496,7 +489,7 @@ int srslte_ulsch_decode(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuf
}
/* UL-SCH channel interleaver according to 5.5.2.8 of 36.212 */
/* UL-SCH channel interleaver according to 5.2.2.8 of 36.212 */
void ulsch_interleave(srslte_uci_pos_t *q, uint8_t *g_bits, uint32_t Qm, uint32_t H_prime_total,
uint32_t N_pusch_symbs, uint8_t *q_bits)
{

@ -202,16 +202,18 @@ int main(int argc, char **argv) {
data[i] = 1;
}
gettimeofday(&t[1], NULL);
if (srslte_softbuffer_tx_init(&softbuffer, 4*cell.nof_prb)) {
fprintf(stderr, "Error initiating soft buffer\n");
goto quit;
}
gettimeofday(&t[1], NULL);
for (int i=0;i<10;i++) {
if (srslte_pusch_uci_encode(&pusch, &cfg, &softbuffer, data, uci_data, sf_symbols)) {
fprintf(stderr, "Error encoding TB\n");
exit(-1);
}
}
if (rv_idx > 0) {
cfg.rv = rv_idx;
if (srslte_pusch_uci_encode(&pusch, &cfg, &softbuffer, data, uci_data, sf_symbols)) {
@ -232,10 +234,10 @@ int main(int argc, char **argv) {
goto quit;
} else {
printf("ENCODED OK in %d:%d (TBS: %d bits, TX: %.2f Mbps, Processing: %.2f Mbps)\n", (int) t[0].tv_sec,
(int) t[0].tv_usec,
(int) t[0].tv_usec/10,
cfg.grant.mcs.tbs,
(float) cfg.grant.mcs.tbs/1000,
(float) cfg.grant.mcs.tbs/t[0].tv_usec);
(float) cfg.grant.mcs.tbs/t[0].tv_usec*10);
}
ret = 0;

@ -69,6 +69,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
cell.id=1;
cell.cp=SRSLTE_CP_NORM;
srslte_verbose = SRSLTE_VERBOSE_DEBUG;
if (srslte_softbuffer_tx_init(&softbuffer, cell.nof_prb)) {
mexErrMsgTxt("Error initiating HARQ\n");
return;

Loading…
Cancel
Save