Integrated RM lut in sch.c

This commit is contained in:
ismagom 2015-09-16 20:49:48 +02:00
parent 784aea119b
commit df9ef48d53
7 changed files with 141 additions and 147 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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_idx<SRSLTE_NOF_TC_CB_SIZES;cb_idx++) {
int cb_len=srslte_cbsegm_cbsize(cb_idx);
int in_len=3*cb_len+12;
int nrows = (in_len / 3 - 1) / NCOLS + 1;
int K_p = nrows * NCOLS;
int ndummy = K_p - in_len / 3;
if (ndummy < 0) {
ndummy = 0;
}
if (!rm_turbo_tables_generated) {
rm_turbo_tables_generated = true;
for (int cb_idx=0;cb_idx<SRSLTE_NOF_TC_CB_SIZES;cb_idx++) {
int cb_len=srslte_cbsegm_cbsize(cb_idx);
int in_len=3*cb_len+12;
int nrows = (in_len / 3 - 1) / NCOLS + 1;
int K_p = nrows * NCOLS;
int ndummy = K_p - in_len / 3;
if (ndummy < 0) {
ndummy = 0;
}
for (int i=0;i<4;i++) {
k0_vec[cb_idx][i][0] = nrows * (2 * (uint32_t) ceilf((float) (3*K_p) / (float) (8 * nrows)) * i + 2);
k0_vec[cb_idx][i][1] = -1;
for (int i=0;i<4;i++) {
k0_vec[cb_idx][i][0] = nrows * (2 * (uint32_t) ceilf((float) (3*K_p) / (float) (8 * nrows)) * i + 2);
k0_vec[cb_idx][i][1] = -1;
}
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);
}
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);
}
}
}
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 rv_idx) {

View File

@ -184,99 +184,102 @@ 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, srslte_tcod_out_t *output, uint32_t long_cb)
int srslte_tcod_encode_lut(srslte_tcod_t *h, uint8_t *input, uint8_t *parity, uint32_t cblen_idx)
{
if (long_cb % 8) {
fprintf(stderr, "Turbo coder LUT implementation long_cb must be multiple of 8\n");
if (cblen_idx < 188) {
uint32_t long_cb = srslte_cbsegm_cbsize(cblen_idx);
if (long_cb % 8) {
fprintf(stderr, "Turbo coder LUT implementation long_cb must be multiple of 8\n");
return -1;
}
/* Parity bits for the 1st constituent encoders */
uint8_t state0 = 0;
for (uint32_t i=0;i<long_cb/8;i++) {
parity[i] = tcod_lut_output[cblen_idx][state0][input[i]];
state0 = tcod_lut_next_state[cblen_idx][state0][input[i]] % 8;
}
/* Interleave input */
srslte_bit_interleave(input, h->temp, tcod_per_fw[cblen_idx], long_cb);
/* Parity bits for the 2nd constituent encoders */
uint8_t state1 = 0;
for (uint32_t i=0;i<long_cb/8;i++) {
parity[long_cb/8+i] = tcod_lut_output[cblen_idx][state1][h->temp[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;i<long_cb/8;i++) {
output->parity1[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;i<long_cb/8;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;
}
/* 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;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;

View File

@ -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");

View File

@ -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);

View File

@ -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<cfg.grant.mcs.tbs;i++) {
for (uint32_t i=0;i<cfg.grant.mcs.tbs/8;i++) {
data[i] = 1;
}