diff --git a/srslte/include/srslte/fec/turbocoder.h b/srslte/include/srslte/fec/turbocoder.h index 89e979fcc..da70a1e32 100644 --- a/srslte/include/srslte/fec/turbocoder.h +++ b/srslte/include/srslte/fec/turbocoder.h @@ -59,11 +59,6 @@ typedef struct SRSLTE_API { * 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); @@ -77,13 +72,8 @@ SRSLTE_API int srslte_tcod_encode(srslte_tcod_t *h, SRSLTE_API int srslte_tcod_encode_lut(srslte_tcod_t *h, uint8_t *input, - 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); + uint8_t *parity, + uint32_t cblen_idx); SRSLTE_API void srslte_tcod_gentable(); diff --git a/srslte/include/srslte/phch/sch.h b/srslte/include/srslte/phch/sch.h index 127e6a886..90811320a 100644 --- a/srslte/include/srslte/phch/sch.h +++ b/srslte/include/srslte/phch/sch.h @@ -68,7 +68,6 @@ 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; diff --git a/srslte/lib/fec/src/rm_turbo.c b/srslte/lib/fec/src/rm_turbo.c index 86e415a52..87328511f 100644 --- a/srslte/lib/fec/src/rm_turbo.c +++ b/srslte/lib/fec/src/rm_turbo.c @@ -48,7 +48,7 @@ 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 k0_vec[SRSLTE_NOF_TC_CB_SIZES][4][2]; - +static bool rm_turbo_tables_generated = false; void srslte_rm_turbo_gentable_systematic(uint32_t *table_bits, uint32_t k0_vec[4][2], uint32_t nrows, int ndummy) { @@ -121,24 +121,27 @@ void srslte_rm_turbo_gentable_parity(uint32_t *table_parity, uint32_t k0_vec[4][ } void srslte_rm_turbo_gentables() { - for (int cb_idx=0;cb_idxtemp, tcod_per_fw[cblen_idx], long_cb); + + /* Parity bits for the 2nd constituent encoders */ + uint8_t state1 = 0; + for (uint32_t i=0;itemp[i]]; + state1 = tcod_lut_next_state[cblen_idx][state1][h->temp[i]] % 8; + } + + /* Tail bits */ + 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; + reg2_2 = state1&1; + + reg1_0 = (state0&4)>>2; + reg1_1 = (state0&2)>>1; + reg1_2 = state0&1; + + /* TAILING CODER #1 */ + for (uint32_t j = 0; j < NOF_REGS; j++) { + bit = reg1_2 ^ reg1_1; + + tail[k] = bit; + k++; + + in = bit ^ (reg1_2 ^ reg1_1); + out = reg1_2 ^ (reg1_0 ^ in); + + reg1_2 = reg1_1; + reg1_1 = reg1_0; + reg1_0 = in; + + tail[k] = out; + k++; + } + + /* TAILING CODER #2 */ + for (uint32_t j = 0; j < NOF_REGS; j++) { + bit = reg2_2 ^ reg2_1; + + tail[k] = bit; + k++; + + in = bit ^ (reg2_2 ^ reg2_1); + out = reg2_2 ^ (reg2_0 ^ in); + + reg2_2 = reg2_1; + reg2_1 = reg2_0; + reg2_0 = in; + + tail[k] = out; + k++; + } + + uint8_t tailv[3][4]; + for (int i=0;i<4;i++) { + for (int j=0;j<3;j++) { + tailv[j][i] = tail[3*i+j]; + } + } + uint8_t *x = tailv[0]; + input[long_cb/8] = srslte_bit_pack(&x, 4); + x = tailv[1]; + parity[long_cb/8] = srslte_bit_pack(&x, 4); + x = tailv[2]; + parity[2*long_cb/8] = srslte_bit_pack(&x, 4); + + return 3*long_cb+TOTALTAIL; + } else { return -1; } - - int ret = srslte_cbsegm_cbindex(long_cb); - if (ret < 0) { - return -1; - } - uint8_t len_idx = (uint8_t) ret; - - /* Parity bits for the 1st constituent encoders */ - uint8_t state0 = 0; - for (uint32_t i=0;iparity1[i] = tcod_lut_output[len_idx][state0][input[i]]; - state0 = tcod_lut_next_state[len_idx][state0][input[i]] % 8; - } - - /* Interleave input */ - srslte_bit_interleave(input, h->temp, tcod_per_fw[len_idx], long_cb); - - /* Parity bits for the 2nd constituent encoders */ - uint8_t state1 = 0; - for (uint32_t i=0;iparity2[i] = tcod_lut_output[len_idx][state1][h->temp[i]]; - state1 = tcod_lut_next_state[len_idx][state1][h->temp[i]] % 8; - } - - /* Tail bits */ - uint8_t reg1_0, reg1_1, reg1_2, reg2_0, reg2_1, reg2_2; - uint8_t bit, in, out; - uint8_t k=0; - - reg2_0 = (state1&4)>>2; - reg2_1 = (state1&2)>>1; - reg2_2 = state1&1; - - reg1_0 = (state0&4)>>2; - reg1_1 = (state0&2)>>1; - reg1_2 = state0&1; - - /* TAILING CODER #1 */ - for (uint32_t j = 0; j < NOF_REGS; j++) { - bit = reg1_2 ^ reg1_1; - - output->tail[k] = bit; - k++; - - in = bit ^ (reg1_2 ^ reg1_1); - out = reg1_2 ^ (reg1_0 ^ in); - - reg1_2 = reg1_1; - reg1_1 = reg1_0; - reg1_0 = in; - - output->tail[k] = out; - k++; - } - - /* TAILING CODER #2 */ - for (uint32_t j = 0; j < NOF_REGS; j++) { - bit = reg2_2 ^ reg2_1; - - output->tail[k] = bit; - k++; - - in = bit ^ (reg2_2 ^ reg2_1); - out = reg2_2 ^ (reg2_0 ^ in); - - reg2_2 = reg2_1; - reg2_1 = reg2_0; - reg2_0 = in; - - output->tail[k] = out; - k++; - } - - 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;iparity1[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; diff --git a/srslte/lib/fec/test/turbocoder_test.c b/srslte/lib/fec/test/turbocoder_test.c index 96be68a0a..949cb986b 100644 --- a/srslte/lib/fec/test/turbocoder_test.c +++ b/srslte/lib/fec/test/turbocoder_test.c @@ -63,9 +63,9 @@ 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 output_bits[3*6144+12]; uint8_t output_bits2[3*6144+12]; -srslte_tcod_out_t tcod_output; int main(int argc, char **argv) { @@ -99,9 +99,7 @@ int main(int argc, char **argv) { } srslte_tcod_encode(&tcod, input_bits, output_bits, long_cb); - srslte_tcod_encode_lut(&tcod, input_bytes, &tcod_output, long_cb); - - srslte_tcod_output_to_array(input_bytes, &tcod_output, output_bits2, long_cb); + srslte_tcod_encode_lut(&tcod, input_bytes, parity, long_cb); if (SRSLTE_VERBOSE_ISINFO()) { printf("1st encoder\n"); diff --git a/srslte/lib/phch/src/sch.c b/srslte/lib/phch/src/sch.c index 4fc6e4a19..120f74445 100644 --- a/srslte/lib/phch/src/sch.c +++ b/srslte/lib/phch/src/sch.c @@ -106,6 +106,8 @@ int srslte_sch_init(srslte_sch_t *q) { goto clean; } + srslte_rm_turbo_gentables(); + // Allocate floats for reception (LLRs) q->cb_in = srslte_vec_malloc(sizeof(uint8_t) * SRSLTE_TCOD_MAX_LEN_CB); if (!q->cb_in) { @@ -171,7 +173,7 @@ static int encode_tb(srslte_sch_t *q, uint8_t parity[3] = {0, 0, 0}; uint32_t par; uint32_t i; - uint32_t cb_len, rp, wp, rlen, F, n_e; + uint32_t cb_len, rp, wp, rlen, n_e; int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && @@ -180,6 +182,11 @@ static int encode_tb(srslte_sch_t *q, soft_buffer != NULL) { + if (cb_segm->F) { + fprintf(stderr, "Error filler bits are not supported. Use standard TBS\n"); + return SRSLTE_ERROR; + } + uint32_t Gp = nof_e_bits / Qm; uint32_t gamma = Gp; @@ -220,40 +227,37 @@ static int encode_tb(srslte_sch_t *q, } else { rlen = cb_len; } - if (i == 0) { - F = cb_segm->F; - } else { - F = 0; - } if (i <= cb_segm->C - gamma - 1) { n_e = Qm * (Gp/cb_segm->C); } else { n_e = Qm * ((uint32_t) ceilf((float) Gp/cb_segm->C)); } - INFO("CB#%d: cb_len: %d, rlen: %d, wp: %d, rp: %d, F: %d, E: %d\n", i, - cb_len, rlen - F, wp, rp, F, n_e); + 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 */ if (i < cb_segm->C - 1) { // Copy data - memcpy(&q->cb_in[F/8], &data[rp/8], (rlen - F) * sizeof(uint8_t)/8); + memcpy(q->cb_in, &data[rp/8], rlen * sizeof(uint8_t)/8); } else { INFO("Last CB, appending parity: %d from %d and 24 to %d\n", - rlen - F - 24, rp, rlen - 24); + rlen - 24, rp, rlen - 24); /* Append Transport Block parity bits to the last CB */ - memcpy(&q->cb_in[F/8], &data[rp/8], (rlen - 24 - F) * sizeof(uint8_t)/8); + memcpy(q->cb_in, &data[rp/8], (rlen - 24) * sizeof(uint8_t)/8); memcpy(&q->cb_in[(rlen - 24)/8], parity, 3 * sizeof(uint8_t)); } - /* Filler bits are treated like zeros for the CB CRC calculation */ - for (int j = 0; j < F/8; j++) { - q->cb_in[j] = 0; - } - /* Attach Codeblock CRC */ if (cb_segm->C > 1) { srslte_crc_attach_byte(&q->crc_cb, q->cb_in, rlen); @@ -265,8 +269,7 @@ static int encode_tb(srslte_sch_t *q, } /* Turbo Encoding */ - 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); + srslte_tcod_encode_lut(&q->encoder, q->cb_in, (uint8_t*) q->cb_out, cblen_idx); if (SRSLTE_VERBOSE_ISDEBUG()) { DEBUG("CB#%d encoded: ", i); @@ -275,16 +278,14 @@ static int encode_tb(srslte_sch_t *q, } /* Rate matching */ - if (srslte_rm_turbo_tx(soft_buffer->buffer_b[i], soft_buffer->buff_size, - (uint8_t*) q->cb_out, 3 * cb_len + 12, - &e_bits[wp], n_e, rv)) + if (srslte_rm_turbo_tx_lut(soft_buffer->buffer_b[i], q->cb_in, (uint8_t*) q->cb_out, &e_bits[wp], cblen_idx, n_e, rv)) { fprintf(stderr, "Error in rate matching\n"); return SRSLTE_ERROR; } /* Set read/write pointers */ - rp += (rlen - F); + rp += rlen; wp += n_e; } INFO("END CB#%d: wp: %d, rp: %d\n", i, wp, rp); diff --git a/srslte/lib/phch/test/pusch_test.c b/srslte/lib/phch/test/pusch_test.c index b097db469..364f26adc 100644 --- a/srslte/lib/phch/test/pusch_test.c +++ b/srslte/lib/phch/test/pusch_test.c @@ -167,9 +167,9 @@ int main(int argc, char **argv) { srslte_uci_data_t uci_data; bzero(&uci_data, sizeof(srslte_uci_data_t)); - uci_data.uci_cqi_len = 20; + uci_data.uci_cqi_len = 0; uci_data.uci_ri_len = 0; - uci_data.uci_ack_len = 1; + uci_data.uci_ack_len = 0; for (uint32_t i=0;i<20;i++) { uci_data.uci_cqi [i] = 1; @@ -198,7 +198,7 @@ int main(int argc, char **argv) { goto quit; } - for (uint32_t i=0;i