diff options
author | Joshua Schueler <joshua.schueler@rohde-schwarz.com> | 2017-06-29 13:17:27 +0200 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2018-12-13 20:19:03 -0800 |
commit | 5676739debbdcbf3de658848cc17bdf4e80df36d (patch) | |
tree | 1c850752b6b84e6bcfd3ca51b61dd824a63eb276 /gr-dtv | |
parent | a50812d2b2f8aeb0bf9bd8806b49a32e98866f72 (diff) |
gr-dtv: Generalize BCH speed improvments
This implements the BCH speed improvements for all dvb configurations
Diffstat (limited to 'gr-dtv')
-rw-r--r-- | gr-dtv/lib/dvb/dvb_bch_bb_impl.cc | 390 | ||||
-rw-r--r-- | gr-dtv/lib/dvb/dvb_bch_bb_impl.h | 21 |
2 files changed, 128 insertions, 283 deletions
diff --git a/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc b/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc index fef580acdc..0ec9c2f784 100644 --- a/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc +++ b/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc @@ -371,6 +371,24 @@ namespace gr { } } + switch (bch_code) { + case BCH_CODE_N12: + num_parity_bits = 192; + break; + case BCH_CODE_N10: + num_parity_bits = 160; + break; + case BCH_CODE_N8: + num_parity_bits = 128; + break; + case BCH_CODE_M12: + num_parity_bits = 180; + break; + case BCH_CODE_S12: + num_parity_bits = 168; + break; + } + bch_poly_build_tables(); set_output_multiple(nbch); } @@ -415,103 +433,24 @@ namespace gr { return max + 1; } - /* - * Pack the polynomial into a 32 bit array - */ - void - dvb_bch_bb_impl::poly_pack(const int *pin, unsigned int* pout, int len) - { - int lw = len / 32; - int ptr = 0; - unsigned int temp; - if (len % 32) { - lw++; - } - - for (int i = 0; i < lw; i++) { - temp = 0x80000000; - pout[i] = 0; - for (int j = 0; j < 32; j++) { - if (pin[ptr++]) { - pout[i] |= temp; - } - temp >>= 1; - } - } - } - + //precalculate the crc from: http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html - cf. CRC-32 Lookup void - dvb_bch_bb_impl::poly_reverse(int *pin, int *pout, int len) + dvb_bch_bb_impl::calculate_crc_table(void) { - int c; - c = len - 1; - - for (int i = 0; i < len; i++) { - pout[c--] = pin[i]; - } - } - - /* - *Shift a 128 bit register - */ - inline void - dvb_bch_bb_impl::reg_4_shift(unsigned int *sr) - { - sr[3] = (sr[3] >> 1) | (sr[2] << 31); - sr[2] = (sr[2] >> 1) | (sr[1] << 31); - sr[1] = (sr[1] >> 1) | (sr[0] << 31); - sr[0] = (sr[0] >> 1); - } - - /* - * Shift 160 bits - */ - inline void - dvb_bch_bb_impl::reg_5_shift(unsigned int *sr) - { - sr[4] = (sr[4] >> 1) | (sr[3] << 31); - sr[3] = (sr[3] >> 1) | (sr[2] << 31); - sr[2] = (sr[2] >> 1) | (sr[1] << 31); - sr[1] = (sr[1] >> 1) | (sr[0] << 31); - sr[0] = (sr[0] >> 1); - } + for (int divident = 0; divident < 256; divident++) { /* iterate over all possible input byte values 0 - 255 */ + std::bitset<MAX_BCH_PARITY_BITS> curByte(divident); + curByte <<= num_parity_bits - 8; - /* - * Shift 192 bits - */ - inline void - dvb_bch_bb_impl::reg_6_shift(unsigned int *sr) - { - sr[5] = (sr[5] >> 1) | (sr[4] << 31); - sr[4] = (sr[4] >> 1) | (sr[3] << 31); - sr[3] = (sr[3] >> 1) | (sr[2] << 31); - sr[2] = (sr[2] >> 1) | (sr[1] << 31); - sr[1] = (sr[1] >> 1) | (sr[0] << 31); - 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) - { + for (unsigned char bit = 0; bit < 8; bit++) { + if ((curByte[num_parity_bits - 1]) != 0) { curByte <<= 1; curByte ^= polynome; } - else - { + else { curByte <<= 1; } } - - crcTable[divident] = curByte; + crc_table[divident] = curByte; } } @@ -563,55 +502,73 @@ namespace gr { int len; int polyout[2][200]; - len = poly_mult(polyn01, 17, polyn02, 17, polyout[0]); - len = poly_mult(polyn03, 17, polyout[0], len, polyout[1]); - len = poly_mult(polyn04, 17, polyout[1], len, polyout[0]); - len = poly_mult(polyn05, 17, polyout[0], len, polyout[1]); - len = poly_mult(polyn06, 17, polyout[1], len, polyout[0]); - len = poly_mult(polyn07, 17, polyout[0], len, polyout[1]); - len = poly_mult(polyn08, 17, polyout[1], len, polyout[0]); - poly_pack(polyout[0], m_poly_n_8, 128); - - len = poly_mult(polyn09, 17, polyout[0], len, polyout[1]); - len = poly_mult(polyn10, 17, polyout[1], len, polyout[0]); - poly_pack(polyout[0], m_poly_n_10, 160); - - len = poly_mult(polyn11, 17, polyout[0], len, polyout[1]); - 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]; +#define COPY_BCH_POLYNOME \ +for (unsigned int i = 0; i < num_parity_bits; i ++) {\ + polynome[i] = polyout[0][i];\ +} + + switch (bch_code) { + case BCH_CODE_N12: + case BCH_CODE_N10: + case BCH_CODE_N8: + + len = poly_mult(polyn01, 17, polyn02, 17, polyout[0]); + len = poly_mult(polyn03, 17, polyout[0], len, polyout[1]); + len = poly_mult(polyn04, 17, polyout[1], len, polyout[0]); + len = poly_mult(polyn05, 17, polyout[0], len, polyout[1]); + len = poly_mult(polyn06, 17, polyout[1], len, polyout[0]); + len = poly_mult(polyn07, 17, polyout[0], len, polyout[1]); + len = poly_mult(polyn08, 17, polyout[1], len, polyout[0]); + if (bch_code == BCH_CODE_N8) { + COPY_BCH_POLYNOME + } + + len = poly_mult(polyn09, 17, polyout[0], len, polyout[1]); + len = poly_mult(polyn10, 17, polyout[1], len, polyout[0]); + if (bch_code == BCH_CODE_N10) { + COPY_BCH_POLYNOME + } + + len = poly_mult(polyn11, 17, polyout[0], len, polyout[1]); + len = poly_mult(polyn12, 17, polyout[1], len, polyout[0]); + if (bch_code == BCH_CODE_N12) { + COPY_BCH_POLYNOME + } + break; + + case BCH_CODE_S12: + 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]); + len = poly_mult(polys05, 15, polyout[0], len, polyout[1]); + len = poly_mult(polys06, 15, polyout[1], len, polyout[0]); + len = poly_mult(polys07, 15, polyout[0], len, polyout[1]); + len = poly_mult(polys08, 15, polyout[1], len, polyout[0]); + len = poly_mult(polys09, 15, polyout[0], len, polyout[1]); + len = poly_mult(polys10, 15, polyout[1], len, polyout[0]); + len = poly_mult(polys11, 15, polyout[0], len, polyout[1]); + len = poly_mult(polys12, 15, polyout[1], len, polyout[0]); + + COPY_BCH_POLYNOME + break; + + case BCH_CODE_M12: + len = poly_mult(polym01, 16, polym02, 16, polyout[0]); + len = poly_mult(polym03, 16, polyout[0], len, polyout[1]); + len = poly_mult(polym04, 16, polyout[1], len, polyout[0]); + len = poly_mult(polym05, 16, polyout[0], len, polyout[1]); + len = poly_mult(polym06, 16, polyout[1], len, polyout[0]); + len = poly_mult(polym07, 16, polyout[0], len, polyout[1]); + len = poly_mult(polym08, 16, polyout[1], len, polyout[0]); + len = poly_mult(polym09, 16, polyout[0], len, polyout[1]); + len = poly_mult(polym10, 16, polyout[1], len, polyout[0]); + len = poly_mult(polym11, 16, polyout[0], len, polyout[1]); + len = poly_mult(polym12, 16, polyout[1], len, polyout[0]); + + COPY_BCH_POLYNOME + break; } - 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]); - len = poly_mult(polys05, 15, polyout[0], len, polyout[1]); - len = poly_mult(polys06, 15, polyout[1], len, polyout[0]); - len = poly_mult(polys07, 15, polyout[0], len, polyout[1]); - len = poly_mult(polys08, 15, polyout[1], len, polyout[0]); - len = poly_mult(polys09, 15, polyout[0], len, polyout[1]); - len = poly_mult(polys10, 15, polyout[1], len, polyout[0]); - len = poly_mult(polys11, 15, polyout[0], len, polyout[1]); - len = poly_mult(polys12, 15, polyout[1], len, polyout[0]); - poly_pack(polyout[0], m_poly_s_12, 168); - - len = poly_mult(polym01, 16, polym02, 16, polyout[0]); - len = poly_mult(polym03, 16, polyout[0], len, polyout[1]); - len = poly_mult(polym04, 16, polyout[1], len, polyout[0]); - len = poly_mult(polym05, 16, polyout[0], len, polyout[1]); - len = poly_mult(polym06, 16, polyout[1], len, polyout[0]); - len = poly_mult(polym07, 16, polyout[0], len, polyout[1]); - len = poly_mult(polym08, 16, polyout[1], len, polyout[0]); - len = poly_mult(polym09, 16, polyout[0], len, polyout[1]); - len = poly_mult(polym10, 16, polyout[1], len, polyout[0]); - len = poly_mult(polym11, 16, polyout[0], len, polyout[1]); - len = poly_mult(polym12, 16, polyout[1], len, polyout[0]); - poly_pack(polyout[0], m_poly_m_12, 180); + calculate_crc_table(); } int @@ -623,143 +580,36 @@ namespace gr { const unsigned char *in = (const unsigned char *) input_items[0]; unsigned char *out = (unsigned char *) output_items[0]; unsigned char b, temp; - unsigned int shift[6]; - std::bitset<192> parity_bits; + + // We can use a 192 bits long bitset, all higher bits not used by the bch will just be ignored + std::bitset<MAX_BCH_PARITY_BITS> parity_bits; int consumed = 0; - switch (bch_code) { - case BCH_CODE_N12: - for (int i = 0; i < noutput_items; i += nbch) { - 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++ = (char) parity_bits[191]; - parity_bits <<= 1; - } - } - break; - case BCH_CODE_N10: - for (int i = 0; i < noutput_items; i += nbch) { - //Zero the shift register - memset(shift, 0, sizeof(unsigned int) * 5); - // MSB of the codeword first - for (int j = 0; j < (int)kbch; j++) { - temp = *in++; - *out++ = temp; - consumed++; - b = (temp ^ (shift[4] & 1)); - reg_5_shift(shift); - if (b) { - shift[0] ^= m_poly_n_10[0]; - shift[1] ^= m_poly_n_10[1]; - shift[2] ^= m_poly_n_10[2]; - shift[3] ^= m_poly_n_10[3]; - shift[4] ^= m_poly_n_10[4]; - } - } - // Now add the parity bits to the output - for( int n = 0; n < 160; n++ ) { - *out++ = (shift[4] & 1); - reg_5_shift(shift); - } - } - break; - case BCH_CODE_N8: - for (int i = 0; i < noutput_items; i += nbch) { - //Zero the shift register - memset(shift, 0, sizeof(unsigned int) * 4); - // MSB of the codeword first - for (int j = 0; j < (int)kbch; j++) { - temp = *in++; - *out++ = temp; - consumed++; - b = temp ^ (shift[3] & 1); - reg_4_shift(shift); - if (b) { - shift[0] ^= m_poly_n_8[0]; - shift[1] ^= m_poly_n_8[1]; - shift[2] ^= m_poly_n_8[2]; - shift[3] ^= m_poly_n_8[3]; - } - } - // Now add the parity bits to the output - for (int n = 0; n < 128; n++) { - *out++ = shift[3] & 1; - reg_4_shift(shift); - } - } - break; - case BCH_CODE_S12: - 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] & 0x01000000) ? 1 : 0)); - reg_6_shift(shift); - if (b) { - shift[0] ^= m_poly_s_12[0]; - shift[1] ^= m_poly_s_12[1]; - shift[2] ^= m_poly_s_12[2]; - shift[3] ^= m_poly_s_12[3]; - shift[4] ^= m_poly_s_12[4]; - shift[5] ^= m_poly_s_12[5]; - } - } - // Now add the parity bits to the output - for (int n = 0; n < 168; n++) { - *out++ = (shift[5] & 0x01000000) ? 1 : 0; - reg_6_shift(shift); - } - } - break; - case BCH_CODE_M12: - 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] & 0x00001000) ? 1 : 0)); - reg_6_shift(shift); - if (b) { - shift[0] ^= m_poly_m_12[0]; - shift[1] ^= m_poly_m_12[1]; - shift[2] ^= m_poly_m_12[2]; - shift[3] ^= m_poly_m_12[3]; - shift[4] ^= m_poly_m_12[4]; - shift[5] ^= m_poly_m_12[5]; - } - } - // Now add the parity bits to the output - for (int n = 0; n < 180; n++) { - *out++ = (shift[5] & 0x00001000) ? 1 : 0; - reg_6_shift(shift); - } + for (int i = 0; i < noutput_items; i += nbch) { + 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); } - break; + + unsigned long msB_CRC = (parity_bits >> (num_parity_bits - 8)).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) ^ crc_table[pos]; + } + + // Now add the parity bits to the output + for (unsigned int n = 0; n < num_parity_bits; n++) { + *out++ = (char) parity_bits[num_parity_bits - 1]; + parity_bits <<= 1; + } } // Tell runtime system how many input items we consumed on diff --git a/gr-dtv/lib/dvb/dvb_bch_bb_impl.h b/gr-dtv/lib/dvb/dvb_bch_bb_impl.h index 0a73ee5078..d715161431 100644 --- a/gr-dtv/lib/dvb/dvb_bch_bb_impl.h +++ b/gr-dtv/lib/dvb/dvb_bch_bb_impl.h @@ -25,6 +25,8 @@ #include "dvb_defines.h" #include <bitset> +#define MAX_BCH_PARITY_BITS 192 + namespace gr { namespace dtv { @@ -34,20 +36,13 @@ namespace gr { unsigned int kbch; unsigned int nbch; unsigned int bch_code; - unsigned int m_poly_n_8[4]; - unsigned int m_poly_n_10[5]; - 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(); + + std::bitset<MAX_BCH_PARITY_BITS> crc_table[256]; + unsigned int num_parity_bits; + std::bitset<MAX_BCH_PARITY_BITS> polynome; + + void calculate_crc_table(); int poly_mult(const int*, int, const int*, int, int*); - void poly_pack(const int*, unsigned int*, int); - void poly_reverse(int*, int*, int); - inline void reg_4_shift(unsigned int*); - inline void reg_5_shift(unsigned int*); - inline void reg_6_shift(unsigned int*); void bch_poly_build_tables(void); public: |