summaryrefslogtreecommitdiff
path: root/gr-fec/include
diff options
context:
space:
mode:
authorJohannes Demel <ufcsy@student.kit.edu>2015-08-12 16:51:02 +0200
committerJohannes Demel <ufcsy@student.kit.edu>2015-09-21 10:46:59 +0200
commitd9719d7da8300c8546b305dab2eff763f47d216f (patch)
treeca8062d252e6e9f2e389fa85f045a92b5218bdee /gr-fec/include
parent73d84a231c31bf8312214b5e3a0a97e15c8db98f (diff)
polar: refarctoring and clean-up
Diffstat (limited to 'gr-fec/include')
-rw-r--r--gr-fec/include/gnuradio/fec/polar_common.h29
-rw-r--r--gr-fec/include/gnuradio/fec/polar_decoder_common.h27
-rw-r--r--gr-fec/include/gnuradio/fec/polar_decoder_sc.h8
-rw-r--r--gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h24
-rw-r--r--gr-fec/include/gnuradio/fec/polar_encoder.h21
5 files changed, 59 insertions, 50 deletions
diff --git a/gr-fec/include/gnuradio/fec/polar_common.h b/gr-fec/include/gnuradio/fec/polar_common.h
index 59e0ad38ba..8bf1a61cd8 100644
--- a/gr-fec/include/gnuradio/fec/polar_common.h
+++ b/gr-fec/include/gnuradio/fec/polar_common.h
@@ -30,7 +30,6 @@
namespace gr {
namespace blocks {
namespace kernel {
- class pack_k_bits;
class unpack_k_bits;
}
}
@@ -42,38 +41,46 @@ namespace gr {
/*!
* \brief POLAR code common operations and attributes
* Erdal Arikan "Channel Polarization: A Method for Contructing Capacity-Achieving Codes for Symmetric Binary-Input Memoryless Channels", 2009
+ * \ingroup error_coding_blk
+ *
+ * \details
+ * polar codes are based on this paper by Erdal Arikan
+ * "Channel Polarization: A Method for Contructing Capacity-Achieving Codes for Symmetric Binary-Input Memoryless Channels", 2009
+ *
+ * class holds common info. It is common to all encoders and decoders.
+ * block_size: MUST be a power of 2.
+ * num_info_bits: any integer <= block_size
+ * frozen_bit_positions: elements specify position of frozen bits in each frame. size MUST be equal to block_size - num_info_bits
+ * frozen_bit_values: desired frozen bit values. '0' appended if smaller than frozen_bit_positions.
*/
class FEC_API polar_common
{
public:
- polar_common(int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed = false);
+ polar_common(int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values);
~polar_common();
protected:
const int block_size()const {return d_block_size;};
const int block_power()const {return d_block_power;};
const int num_info_bits() const {return d_num_info_bits;};
- const bool is_packed() const {return d_is_packed;};
// helper functions
long bit_reverse(long value, int active_bits) const;
void print_packed_bit_array(const unsigned char* printed_array, const int num_bytes) const;
void print_unpacked_bit_array(const unsigned char* bits, const unsigned int num_bytes) const;
- const gr::blocks::kernel::unpack_k_bits* unpacker() const {return d_unpacker;};
- std::vector<int> info_bit_position_vector();
+
+ std::vector<int> d_frozen_bit_positions;
+ std::vector<char> d_frozen_bit_values;
+ std::vector<int> d_info_bit_positions;
private:
int d_block_size; // depending on paper called 'N' or 'm'
int d_block_power;
int d_num_info_bits; // mostly abbreviated by 'K'
- bool d_is_packed;
- std::vector<int> d_frozen_bit_positions;
- std::vector<int> d_info_bit_positions;
- std::vector<char> d_frozen_bit_values;
+
void initialize_info_bit_position_vector();
- gr::blocks::kernel::pack_k_bits *d_packer;
- gr::blocks::kernel::unpack_k_bits *d_unpacker;
+ gr::blocks::kernel::unpack_k_bits *d_unpacker; // convenience for 'print_packed_bit_array' function.
};
} // namespace fec
diff --git a/gr-fec/include/gnuradio/fec/polar_decoder_common.h b/gr-fec/include/gnuradio/fec/polar_decoder_common.h
index 61a6564cc6..6f192e5fdd 100644
--- a/gr-fec/include/gnuradio/fec/polar_decoder_common.h
+++ b/gr-fec/include/gnuradio/fec/polar_decoder_common.h
@@ -38,18 +38,18 @@ namespace gr {
class FEC_API polar_decoder_common : public generic_decoder, public polar_common
{
public:
- polar_decoder_common(int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed);
+ polar_decoder_common(int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values);
~polar_decoder_common();
// FECAPI
double rate(){return (1.0 * get_input_size() / get_output_size());};
- int get_input_size(){return block_size() / (is_packed() ? 8 : 1);};
- int get_output_size(){return num_info_bits() / (is_packed() ? 8 : 1);};
+ int get_input_size(){return block_size();};
+ int get_output_size(){return num_info_bits();};
bool set_frame_size(unsigned int frame_size){return false;};
- const char* get_output_conversion() {return "none";};
private:
- const float D_LLR_FACTOR;
+ static const float D_LLR_FACTOR = -2.19722458f;
+ unsigned int d_frozen_bit_counter;
protected:
// calculate LLRs for stage
@@ -57,26 +57,21 @@ namespace gr {
float llr_even(const float la, const float lb, const unsigned char f) const;
unsigned char llr_bit_decision(const float llr) const {return (llr < 0.0f) ? 1 : 0;};
+ // control retrieval of frozen bits.
+ const bool is_frozen_bit(const int u_num) const;
+ const unsigned char next_frozen_bit();
+
// preparation for decoding
- void initialize_llr_vector(float* llrs, const float* input);
+ void initialize_decoder(unsigned char* u, float* llrs, const float* input);
+
// basic algorithm methods
void butterfly(float* llrs, unsigned char* u, const int stage, const int u_num, const int row);
void butterfly_volk(float* llrs, unsigned char* u, const int stage, const int u_num, const int row);
void butterfly_generic(float* llrs, unsigned char* u, const int stage, const int u_num, const int row);
void even_u_values(unsigned char* u_even, const unsigned char* u, const int u_num);
void odd_xor_even_values(unsigned char* u_xor, const unsigned char* u, const int u_num);
- void demortonize_values(unsigned char* u);
-
void extract_info_bits(unsigned char* output, const unsigned char* input) const;
- static void insert_bit_at_pos(unsigned char* u, const unsigned char ui, const unsigned int pos){u[pos >> 3] ^= ui << (7 - (pos % 8));};
- static unsigned char fetch_bit_at_pos(const unsigned char* u, const unsigned int pos){return (u[pos >> 3] >> (7 - (pos % 8))) & 0x01;};
-
- // info shared among all implementations.
- std::vector<int> d_frozen_bit_positions;
- std::vector<int> d_info_bit_positions;
- std::vector<char> d_frozen_bit_values;
-
// helper functions.
void print_pretty_llr_vector(const float* llr_vec) const;
diff --git a/gr-fec/include/gnuradio/fec/polar_decoder_sc.h b/gr-fec/include/gnuradio/fec/polar_decoder_sc.h
index e9fa6a244d..35f22dde5b 100644
--- a/gr-fec/include/gnuradio/fec/polar_decoder_sc.h
+++ b/gr-fec/include/gnuradio/fec/polar_decoder_sc.h
@@ -32,7 +32,7 @@ namespace gr {
namespace fec {
/*!
- * \brief Standard successive cancellation decoder for POLAR codes
+ * \brief Standard successive cancellation (SC) decoder for POLAR codes
* It expects float input with bits mapped 1 --> 1, 0 --> -1
* Or: f = 2.0 * bit - 1.0
*
@@ -40,16 +40,14 @@ namespace gr {
class FEC_API polar_decoder_sc : public polar_decoder_common
{
public:
- static generic_decoder::sptr make(int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed = false);
+ static generic_decoder::sptr make(int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values);
~polar_decoder_sc();
// FECAPI
void generic_work(void *in_buffer, void *out_buffer);
private:
- polar_decoder_sc(int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed);
-
- unsigned int d_frozen_bit_counter;
+ polar_decoder_sc(int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values);
float* d_llr_vec;
unsigned char* d_u_hat_vec;
diff --git a/gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h b/gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h
index 001ef66b1c..5dbad0eefa 100644
--- a/gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h
+++ b/gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h
@@ -35,32 +35,36 @@ namespace gr {
}
/*!
- * \brief implements a successive cancellation list decoder for polar codes
+ * \brief Successive cancellation list (SCL) decoder for polar codes
* decoder is based on Tal, Vardy "List Decoding of Polar Codes", 2012
* LLR version: Balatsoukas-Stimming, Parizi, Burg "LLR-based Successive Cancellation List Decoding of Polar Codes", 2015
*
+ * \details
+ * max_list_size: specifies the maximum number of code paths to follow.
+ *
+ * Block expects float input with bits mapped 1 --> 1, 0 --> -1
+ * Or: f = 2.0 * bit - 1.0
+ *
*/
class FEC_API polar_decoder_sc_list : public polar_decoder_common
{
public:
- static generic_decoder::sptr make(int max_list_size, int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed = false);
+ static generic_decoder::sptr make(int max_list_size, int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values);
~polar_decoder_sc_list();
// FECAPI
void generic_work(void *in_buffer, void *out_buffer);
private:
- polar_decoder_sc_list(int max_list_size, int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed);
+ polar_decoder_sc_list(int max_list_size, int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values);
- unsigned int d_max_list_size;
polar::scl_list* d_scl;
- unsigned int d_frozen_bit_counter;
-
- void decode_list();
- void calculate_next_llr_in_paths(int u_num);
- void calculate_next_llr(polar::path* current_path, int u_num);
- void update_with_frozenbit(const int u_num);
+ void initialize_list(const float* in_buf);
+ const unsigned char* decode_list();
+ void decode_bit(const int u_num);
+ void calculate_llrs_for_list(const int u_num);
+ void set_bit_in_list(const int u_num);
};
} // namespace fec
} // namespace gr
diff --git a/gr-fec/include/gnuradio/fec/polar_encoder.h b/gr-fec/include/gnuradio/fec/polar_encoder.h
index 20ff5dc3b1..530a6ded40 100644
--- a/gr-fec/include/gnuradio/fec/polar_encoder.h
+++ b/gr-fec/include/gnuradio/fec/polar_encoder.h
@@ -33,6 +33,13 @@ namespace gr {
/*!
* \brief POLAR encoder
+ * for basic details see 'polar_common' class.
+ * \ingroup error_coding_blk
+ *
+ * \details
+ * Additional parameters
+ * is_packed: choose 1 active bit/byte or 8 active bit/byte.
+ * if false, VOLK polar encoder is used.
*
*/
class FEC_API polar_encoder : public generic_encoder, public polar_common
@@ -44,23 +51,21 @@ namespace gr {
// FECAPI
void generic_work(void *in_buffer, void *out_buffer);
double rate(){return (1.0 * get_input_size() / get_output_size());};
- int get_input_size(){return num_info_bits() / (is_packed() ? 8 : 1);};
- int get_output_size(){return block_size() / (is_packed() ? 8 : 1);};
+ int get_input_size(){return num_info_bits() / (d_is_packed ? 8 : 1);};
+ int get_output_size(){return block_size() / (d_is_packed ? 8 : 1);};
bool set_frame_size(unsigned int frame_size){return false;};
- const char* get_input_conversion(){return is_packed() ? "pack" : "none";};
- const char* get_output_conversion(){return is_packed() ? "packed_bits" : "none";};
+ const char* get_input_conversion(){return d_is_packed ? "pack" : "none";};
+ const char* get_output_conversion(){return d_is_packed ? "packed_bits" : "none";};
private:
polar_encoder(int block_size, int num_info_bits, std::vector<int>& frozen_bit_positions, std::vector<char>& frozen_bit_values, bool is_packed);
- std::vector<int> d_frozen_bit_positions;
- std::vector<int> d_info_bit_positions;
- std::vector<char> d_frozen_bit_values;
+ std::vector<int> d_info_bit_reversed_positions;
+ bool d_is_packed;
// c'tor method for packed algorithm setup.
void setup_frozen_bit_inserter();
// methods insert input bits and frozen bits into packed array for encoding
- unsigned char* d_block_array; // use for encoding
unsigned char* d_frozen_bit_prototype; // packed frozen bits are written onto it and later copies are used.
void insert_packed_frozen_bits_and_reverse(unsigned char* target, const unsigned char* input) const;
void insert_unpacked_bit_into_packed_array_at_position(unsigned char* target, const unsigned char bit, const int pos) const;