summaryrefslogtreecommitdiff
path: root/gr-dtv
diff options
context:
space:
mode:
authorJoshua Schueler <joshua.schueler@rohde-schwarz.com>2017-06-29 14:58:10 +0200
committerMartin Braun <martin.braun@ettus.com>2018-12-13 20:19:03 -0800
commit97dff6c55c42d10ec9bc540edf959e11bb82cad8 (patch)
treed52de344ce6568bae26cef61b7939324fe866978 /gr-dtv
parentf00e76c8b87d8b45db4e8f053658d54fb9cde0ad (diff)
gr-dtv: Change the layout of the ldpc table
Previous behaviour with two tables: ldpc_encode.d has all data bits [0, 0, 0, 0, 1, 1, 1, 1 ...] ldpc_encode.p has the corresponding parity bits [40, 333, 4342, 11, 231, 32, 555, 2332, ...] the general work function iterates over both and xors each data bit in the corresponding parity bit position. The new algorithm uses a two-dimensional array [ number of entries, entry1, entry2, ... [5, 4343, 42, 2342, 42342, 244], // parity bit 0 [5, 22, 4455, 6456, 6345, 2424], // parity bit 1 ... ] This makes the general work function a bit simpler and apparently improves the CPU caching behaviour originally written by Team "3-QAM" @ Rohde & Schwarz Engineering Competition 2017
Diffstat (limited to 'gr-dtv')
-rw-r--r--gr-dtv/lib/dvb/dvb_ldpc_bb_impl.cc66
-rw-r--r--gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h9
2 files changed, 49 insertions, 26 deletions
diff --git a/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.cc b/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.cc
index 84328e1200..e907bbb499 100644
--- a/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.cc
+++ b/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.cc
@@ -364,6 +364,8 @@ namespace gr {
*/
dvb_ldpc_bb_impl::~dvb_ldpc_bb_impl()
{
+ delete[] ldpc_lut[0];
+ delete[] ldpc_lut;
}
void
@@ -373,29 +375,48 @@ namespace gr {
}
#define LDPC_BF(TABLE_NAME, ROWS) \
+for (int row = 0; row < ROWS; row++) { /* count the entries in the table */ \
+ max_lut_arraysize += TABLE_NAME[row][0]; \
+} \
+max_lut_arraysize *= 360; /* 360 bits per table entry */ \
+max_lut_arraysize /= pbits; /* spread over all parity bits */ \
+max_lut_arraysize += 2; /* 1 for the size at the start of the array, one as buffer */ \
+\
+/* Allocate a 2D Array with pbits * max_lut_arraysize
+ * while preserving two-subscript access
+ * see https://stackoverflow.com/questions/29375797/copy-2d-array-using-memcpy/29375830#29375830
+ */ \
+ldpc_lut = new int*[pbits]; \
+ldpc_lut[0] = new int[pbits * max_lut_arraysize]; \
+ldpc_lut[0][0] = 1; \
+for (int i = 1; i < pbits; i++) { \
+ ldpc_lut[i] = ldpc_lut[i-1] + max_lut_arraysize; \
+ ldpc_lut[i][0] = 1; \
+} \
for (int row = 0; row < ROWS; row++) { \
for (int n = 0; n < 360; n++) { \
for (int col = 1; col <= TABLE_NAME[row][0]; col++) { \
- ldpc_encode.p[index] = (TABLE_NAME[row][col] + (n * q)) % pbits; \
- ldpc_encode.d[index] = im; \
- index++; \
+ int current_pbit = (TABLE_NAME[row][col] + (n * q)) % pbits; \
+ ldpc_lut[current_pbit][ldpc_lut[current_pbit][0]] = im; \
+ ldpc_lut[current_pbit][0]++; \
} \
im++; \
} \
-}
+}
+ /*
+ * fill the lookup table, for each paritybit it contains
+ * {number of infobits, infobit1, infobit2, ... ]
+ * maximum number of infobits is calculated using the entries
+ * in the ldpc tables
+ */
void
dvb_ldpc_bb_impl::ldpc_lookup_generate(void)
{
- int im;
- int index;
- int pbits;
- int q;
- index = 0;
- im = 0;
-
- pbits = (frame_size_real + Xp) - nbch; //number of parity bits
- q = q_val;
+ int im = 0;
+ int pbits = (frame_size_real + Xp) - nbch; //number of parity bits
+ int q = q_val;
+ int max_lut_arraysize = 0;
if (frame_size_type == FECFRAME_NORMAL) {
if (code_rate == C1_4) {
@@ -593,7 +614,6 @@ for (int row = 0; row < ROWS; row++) { \
LDPC_BF(ldpc_tab_1_3M, 30);
}
}
- ldpc_encode.table_length = index;
}
int
@@ -628,14 +648,20 @@ for (int row = 0; row < ROWS; row++) { \
}
// First zero all the parity bits
memset(p, 0, sizeof(unsigned char) * plen);
- for (int j = 0; j < (int)nbch; j++) {
- out[i + j] = in[consumed];
- consumed++;
- }
+
+ // copy the information bits
+ memcpy(&out[i], &in[consumed], sizeof(unsigned char)*nbch);
+ consumed += nbch;
+
// now do the parity checking
- for (int j = 0; j < ldpc_encode.table_length; j++) {
- p[ldpc_encode.p[j]] ^= d[ldpc_encode.d[j]];
+ for (int i_p = 0; i_p < plen; i_p++) {
+ unsigned char pbit = 0;
+ for (int i_d = 1; i_d < ldpc_lut[i_p][0]; i_d++) {
+ pbit ^= d[ldpc_lut[i_p][i_d]];
+ }
+ p[i_p] = pbit;
}
+
if (P != 0) {
puncture = 0;
for (int j = 0; j < plen; j += P) {
diff --git a/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h b/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h
index c8f0fab698..5506411956 100644
--- a/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h
+++ b/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h
@@ -23,12 +23,8 @@
#include <gnuradio/dtv/dvb_ldpc_bb.h>
#include "dvb_defines.h"
+#include <boost/smart_ptr.hpp>
-typedef struct{
- int table_length;
- int d[LDPC_ENCODE_TABLE_LENGTH];
- int p[LDPC_ENCODE_TABLE_LENGTH];
-}ldpc_encode_table;
namespace gr {
namespace dtv {
@@ -50,7 +46,8 @@ namespace gr {
unsigned char puncturing_buffer[FRAME_SIZE_NORMAL];
unsigned char shortening_buffer[FRAME_SIZE_NORMAL];
void ldpc_lookup_generate(void);
- ldpc_encode_table ldpc_encode;
+
+ int** ldpc_lut;
const static int ldpc_tab_1_4N[45][13];
const static int ldpc_tab_1_3N[60][13];