SCH Codeblock CRC is computed at same time than parity 0

master
Xavier Arteaga 7 years ago
parent c1a0b17c40
commit a21db86a78

@ -63,7 +63,21 @@ SRSLTE_API uint32_t srslte_crc_attach(srslte_crc_t *h,
SRSLTE_API uint32_t srslte_crc_attach_byte(srslte_crc_t *h,
uint8_t *data,
int len);
int len);
static inline void srslte_crc_checksum_put_byte(srslte_crc_t *h, uint8_t byte) {
// Polynom order 8, 16, 24 or 32 only.
int ord = h->order - 8;
uint64_t crc = h->crcinit;
crc = (crc << 8) ^ h->table[((crc >> (ord)) & 0xff) ^ byte];
h->crcinit = crc;
}
static inline uint64_t srslte_crc_checksum_get(srslte_crc_t *h) {
return (h->crcinit & h->crcmask);
}
SRSLTE_API uint32_t srslte_crc_checksum_byte(srslte_crc_t *h,
uint8_t *data,

@ -40,6 +40,7 @@
#include "srslte/config.h"
#include "srslte/phy/fec/tc_interl.h"
#include "srslte/phy/fec/crc.h"
#define SRSLTE_TCOD_MAX_LEN_CB_BYTES (6144/8)
@ -68,7 +69,8 @@ SRSLTE_API int srslte_tcod_encode(srslte_tcod_t *h,
uint8_t *output,
uint32_t long_cb);
SRSLTE_API int srslte_tcod_encode_lut(srslte_tcod_t *h,
SRSLTE_API int srslte_tcod_encode_lut(srslte_tcod_t *h,
srslte_crc_t *crc,
uint8_t *input,
uint8_t *parity,
uint32_t cblen_idx);

@ -48,17 +48,6 @@ void gen_crc_table(srslte_crc_t *h) {
}
}
uint64_t crctable(srslte_crc_t *h, uint8_t byte) {
// Polynom order 8, 16, 24 or 32 only.
int ord = h->order - 8;
uint64_t crc = h->crcinit;
crc = (crc << 8) ^ h->table[((crc >> (ord)) & 0xff) ^ byte];
h->crcinit = crc;
return (crc & h->crcmask);
}
uint64_t reversecrcbit(uint32_t crc, int nbits, srslte_crc_t *h) {
uint64_t m, rmask = 0x1;
@ -137,8 +126,9 @@ uint32_t srslte_crc_checksum(srslte_crc_t *h, uint8_t *data, int len) {
} else {
byte = (uint8_t) (srslte_bit_pack(&pter, 8) & 0xFF);
}
crc = crctable(h, byte);
srslte_crc_checksum_put_byte(h, byte);
}
crc = (uint32_t) srslte_crc_checksum_get(h);
// Reverse CRC res8 positions
if (a == 1) {
@ -159,8 +149,9 @@ uint32_t srslte_crc_checksum_byte(srslte_crc_t *h, uint8_t *data, int len) {
// Calculate CRC
for (i = 0; i < len/8; i++) {
crc = crctable(h, data[i]);
srslte_crc_checksum_put_byte(h, data[i]);
}
crc = (uint32_t) srslte_crc_checksum_get(h);
return crc;

@ -97,7 +97,7 @@ int main(int argc, char **argv) {
}
srslte_tcod_encode(&tcod, input_bits, output_bits, long_cb);
srslte_tcod_encode_lut(&tcod, input_bytes, parity, len);
srslte_tcod_encode_lut(&tcod, NULL, input_bytes, parity, len);
srslte_bit_unpack_vector(parity, parity_bits, 2*(long_cb+4));

@ -29,6 +29,7 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <srslte/phy/fec/crc.h>
#include "srslte/phy/fec/cbsegm.h"
#include "srslte/phy/fec/turbocoder.h"
@ -40,9 +41,13 @@
#define RATE 3
#define TOTALTAIL 12
uint8_t tcod_lut_next_state[188][8][256];
uint8_t tcod_lut_output[188][8][256];
uint16_t tcod_per_fw[188][6144];
typedef struct {
uint8_t next_state;
uint8_t output;
} tcod_lut_t;
static tcod_lut_t tcod_lut[188][8][256];
static uint16_t tcod_per_fw[188][6144];
static srslte_bit_interleaver_t tcod_interleavers[188];
static bool table_initiated = false;
@ -187,23 +192,59 @@ 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 *parity, uint32_t cblen_idx)
int srslte_tcod_encode_lut(srslte_tcod_t *h, srslte_crc_t *crc, uint8_t *input, uint8_t *parity, uint32_t cblen_idx)
{
if (cblen_idx < 188) {
uint32_t long_cb = srslte_cbsegm_cbsize(cblen_idx);
uint32_t long_cb = (uint32_t) 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;
}
/* Reset CRC */
if (crc) {
srslte_crc_set_init(crc, 0);
}
/* 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;
uint8_t state0 = 0;
if (crc) {
/* if CRC pointer is given */
for (int i = 0; i < (long_cb - crc->order) / 8; i++) {
uint8_t in = input[i];
/* Put byte in CRC and save latest checksum */
srslte_crc_checksum_put_byte(crc, in);
/* Run actual encoder */
tcod_lut_t l = tcod_lut[cblen_idx][state0][in];
parity[i] = l.output;
state0 = l.next_state;
}
uint32_t checksum = (uint32_t) srslte_crc_checksum_get(crc);
for (int i = 0; i < crc->order / 8; i++) {
int mask_shift = 8 * (crc->order / 8 - i - 1);
int idx = (long_cb - crc->order) / 8 + i;
uint8_t in = (uint8_t) ((checksum >> mask_shift) & 0xff);
input[idx] = in;
tcod_lut_t l = tcod_lut[cblen_idx][state0][in];
parity[idx] = l.output;
state0 = l.next_state;
}
} else {
/* No CRC given */
for (uint32_t i = 0; i < long_cb / 8; i++) {
tcod_lut_t l = tcod_lut[cblen_idx][state0][input[i]];
parity[i] = l.output;
state0 = l.next_state;
}
}
parity[long_cb/8] = 0; // will put tail here later
parity[long_cb / 8] = 0; // will put tail here later
/* Interleave input */
srslte_bit_interleaver_run(&tcod_interleavers[cblen_idx], input, h->temp, 0);
@ -212,10 +253,11 @@ int srslte_tcod_encode_lut(srslte_tcod_t *h, uint8_t *input, uint8_t *parity, ui
/* Parity bits for the 2nd constituent encoders */
uint8_t state1 = 0;
for (uint32_t i=0;i<long_cb/8;i++) {
uint8_t out = tcod_lut_output[cblen_idx][state1][h->temp[i]];
tcod_lut_t l = tcod_lut[cblen_idx][state1][h->temp[i]];
uint8_t out = l.output;
parity[long_cb/8+i] |= (out&0xf0)>>4;
parity[long_cb/8+i+1] = (out&0xf)<<4;
state1 = tcod_lut_next_state[cblen_idx][state1][h->temp[i]] % 8;
parity[long_cb/8+i+1] = (out&0xf)<<4;
state1 = l.next_state;
}
/* Tail bits */
@ -318,7 +360,7 @@ void srslte_tcod_gentable() {
reg_1 = (state&2)>>1;
reg_2 = state&1;
tcod_lut_output[len][state][data] = 0;
tcod_lut[len][state][data].output = 0;
uint8_t bit, in, out;
for (uint32_t i = 0; i < 8; i++) {
bit = (data&(1<<(7-i)))?1:0;
@ -330,10 +372,10 @@ void srslte_tcod_gentable() {
reg_1 = reg_0;
reg_0 = in;
tcod_lut_output[len][state][data] |= out<<(7-i);
tcod_lut[len][state][data].output |= out<<(7-i);
}
tcod_lut_next_state[len][state][data] = reg_0<<2 | reg_1<<1 | reg_2;
tcod_lut[len][state][data].next_state = (uint8_t) ((reg_0 << 2 | reg_1 << 1 | reg_2) % 8);
}
}
}

@ -264,15 +264,12 @@ static int encode_tb_off(srslte_sch_t *q,
/* Append Transport Block parity bits to the last CB */
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));
}
/* Attach Codeblock CRC */
if (cb_segm->C > 1) {
srslte_crc_attach_byte(&q->crc_cb, q->cb_in, rlen);
}
/* Turbo Encoding */
srslte_tcod_encode_lut(&q->encoder, q->cb_in, q->parity_bits, cblen_idx);
/* Turbo Encoding
* If Codeblock CRC is required it is given the CRC instance pointer, otherwise CRC pointer shall be NULL
*/
srslte_tcod_encode_lut(&q->encoder, (cb_segm->C > 1) ? &q->crc_cb : NULL, q->cb_in, q->parity_bits, cblen_idx);
}
DEBUG("RM cblen_idx=%d, n_e=%d, wp=%d, nof_e_bits=%d\n",cblen_idx, n_e, wp, nof_e_bits);

Loading…
Cancel
Save