summaryrefslogtreecommitdiff
path: root/gr-dtv
diff options
context:
space:
mode:
authorJulius Durst <julius.durst@student.kit.edu>2017-05-29 01:14:10 +0200
committerMartin Braun <martin.braun@ettus.com>2018-12-13 20:19:03 -0800
commita50812d2b2f8aeb0bf9bd8806b49a32e98866f72 (patch)
tree946b060145516e67ab3e210e91d087a4be5d70ca /gr-dtv
parent76538055531207b36528484d86e9cb1a632c9d7b (diff)
gr-dtv: Implement the dvb bch encoder using an improved algorithm
This commit uses a bitset to represent the shift register and precomputes all dividents for the bch encoder to efficiently compute the checksum. written by Team "Barkhausens Army" @ Rohde & Schwarz Engineering Competition 2017
Diffstat (limited to 'gr-dtv')
-rw-r--r--gr-dtv/lib/dvb/dvb_bch_bb_impl.cc69
-rw-r--r--gr-dtv/lib/dvb/dvb_bch_bb_impl.h4
2 files changed, 55 insertions, 18 deletions
diff --git a/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc b/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc
index 8d89f9b04a..fef580acdc 100644
--- a/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc
+++ b/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc
@@ -490,6 +490,31 @@ namespace gr {
sr[0] = (sr[0] >> 1);
}
+ //precalculate the crc from: http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html - cf. CRC-32 Lookup
+ void dvb_bch_bb_impl::CalculateCrcTable()
+ {
+ for (int divident = 0; divident < 256; divident++) /* iterate over all possible input byte values 0 - 255 */
+ {
+ std::bitset<192> curByte(divident);
+ curByte <<= 184;
+
+ for (unsigned char bit = 0; bit < 8; bit++)
+ {
+ if ((curByte[191]) != 0)
+ {
+ curByte <<= 1;
+ curByte ^= polynome;
+ }
+ else
+ {
+ curByte <<= 1;
+ }
+ }
+
+ crcTable[divident] = curByte;
+ }
+ }
+
void
dvb_bch_bb_impl::bch_poly_build_tables(void)
{
@@ -555,6 +580,13 @@ namespace gr {
len = poly_mult(polyn12, 17, polyout[1], len, polyout[0]);
poly_pack(polyout[0], m_poly_n_12, 192);
+ //pack the polynome in a bitset
+ for (int i = 0; i < 192; i += 1) {
+ polynome[i] = polyout[0][i];
+ }
+ CalculateCrcTable();
+
+
len = poly_mult(polys01, 15, polys02, 15, polyout[0]);
len = poly_mult(polys03, 15, polyout[0], len, polyout[1]);
len = poly_mult(polys04, 15, polyout[1], len, polyout[0]);
@@ -592,33 +624,34 @@ namespace gr {
unsigned char *out = (unsigned char *) output_items[0];
unsigned char b, temp;
unsigned int shift[6];
+ std::bitset<192> parity_bits;
int consumed = 0;
switch (bch_code) {
case BCH_CODE_N12:
for (int i = 0; i < noutput_items; i += nbch) {
- //Zero the shift register
- memset(shift, 0, sizeof(unsigned int) * 6);
- // MSB of the codeword first
- for (int j = 0; j < (int)kbch; j++) {
- temp = *in++;
- *out++ = temp;
- consumed++;
- b = (temp ^ (shift[5] & 1));
- reg_6_shift(shift);
- if (b) {
- shift[0] ^= m_poly_n_12[0];
- shift[1] ^= m_poly_n_12[1];
- shift[2] ^= m_poly_n_12[2];
- shift[3] ^= m_poly_n_12[3];
- shift[4] ^= m_poly_n_12[4];
- shift[5] ^= m_poly_n_12[5];
+ for (int j = 0; j < (int)kbch/8; j++) {
+ b = 0;
+
+ // calculate the crc using the lookup table, cf. http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html
+ for (int e = 0; e < 8; e++) {
+ temp = *in++;
+ *out++ = temp;
+ consumed++;
+
+ b |= temp << (7 - e);
}
+
+ unsigned long msB_CRC = (parity_bits >> 184).to_ulong();
+ /* XOR-in next input byte into MSB of crc and get this MSB, that's our new intermediate divident */
+ unsigned char pos = (unsigned char)(msB_CRC ^ b);
+ /* Shift out the MSB used for division per lookuptable and XOR with the remainder */
+ parity_bits = (parity_bits << 8) ^ crcTable[pos];
}
// Now add the parity bits to the output
for (int n = 0; n < 192; n++) {
- *out++ = (shift[5] & 1);
- reg_6_shift(shift);
+ *out++ = (char) parity_bits[191];
+ parity_bits <<= 1;
}
}
break;
diff --git a/gr-dtv/lib/dvb/dvb_bch_bb_impl.h b/gr-dtv/lib/dvb/dvb_bch_bb_impl.h
index 56b4772b26..0a73ee5078 100644
--- a/gr-dtv/lib/dvb/dvb_bch_bb_impl.h
+++ b/gr-dtv/lib/dvb/dvb_bch_bb_impl.h
@@ -23,6 +23,7 @@
#include <gnuradio/dtv/dvb_bch_bb.h>
#include "dvb_defines.h"
+#include <bitset>
namespace gr {
namespace dtv {
@@ -38,6 +39,9 @@ namespace gr {
unsigned int m_poly_n_12[6];
unsigned int m_poly_s_12[6];
unsigned int m_poly_m_12[6];
+ std::bitset<192> polynome;
+ std::bitset<192> crcTable[256];
+ void CalculateCrcTable();
int poly_mult(const int*, int, const int*, int, int*);
void poly_pack(const int*, unsigned int*, int);
void poly_reverse(int*, int*, int);