diff options
author | Johannes Demel <ufcsy@student.kit.edu> | 2015-08-12 16:51:02 +0200 |
---|---|---|
committer | Johannes Demel <ufcsy@student.kit.edu> | 2015-09-21 10:46:59 +0200 |
commit | d9719d7da8300c8546b305dab2eff763f47d216f (patch) | |
tree | ca8062d252e6e9f2e389fa85f045a92b5218bdee /gr-fec/include | |
parent | 73d84a231c31bf8312214b5e3a0a97e15c8db98f (diff) |
polar: refarctoring and clean-up
Diffstat (limited to 'gr-fec/include')
-rw-r--r-- | gr-fec/include/gnuradio/fec/polar_common.h | 29 | ||||
-rw-r--r-- | gr-fec/include/gnuradio/fec/polar_decoder_common.h | 27 | ||||
-rw-r--r-- | gr-fec/include/gnuradio/fec/polar_decoder_sc.h | 8 | ||||
-rw-r--r-- | gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h | 24 | ||||
-rw-r--r-- | gr-fec/include/gnuradio/fec/polar_encoder.h | 21 |
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; |