Skip to content

Commit

Permalink
update to newer version of viterbi decoder library. use sse4.1
Browse files Browse the repository at this point in the history
  • Loading branch information
marenz2569 committed Jul 11, 2023
1 parent c87e0d8 commit 0760983
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 28 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ add_executable(tetra-viterbi
src/examples/viter_bi_codec.cpp
src/examples/tetra_viterbi.cpp)

target_compile_options(tetra PUBLIC -std=c++17 -Wall -Wno-unused-variable)
target_compile_options(tetra PUBLIC -std=c++17 -Wall -Wno-unused-variable -msse4.1)
target_compile_options(tetra-puncturing PUBLIC -std=c++17 -Wall -Wno-unused-variable)
target_compile_options(tetra-viterbi PUBLIC -std=c++17 -Wall -Wno-unused-variable)

Expand Down
4 changes: 2 additions & 2 deletions include/l2/lower_mac.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ class LowerMac {
[[nodiscard]] static auto deinterleave(const std::vector<uint8_t>& data, uint32_t K, uint32_t a) noexcept
-> std::vector<uint8_t>;
[[nodiscard]] static auto depuncture23(const std::vector<uint8_t>& data, uint32_t len) noexcept
-> std::vector<int8_t>;
-> std::vector<int16_t>;
[[nodiscard]] static auto reed_muller_3014_decode(const std::vector<uint8_t>& data) noexcept
-> std::vector<uint8_t>;
[[nodiscard]] static auto check_crc_16_ccitt(const std::vector<uint8_t>& data, int len) noexcept -> int;

[[nodiscard]] auto viter_bi_decode_1614(const std::vector<int8_t>& data) noexcept -> std::vector<uint8_t>;
[[nodiscard]] auto viter_bi_decode_1614(const std::vector<int16_t>& data) noexcept -> std::vector<uint8_t>;
};

#endif
23 changes: 12 additions & 11 deletions include/utils/viter_bi_codec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,30 @@
// include for viterbi algorithm size_t
#include <stdio.h>
#include "viterbi/viterbi_decoder_scalar.h"
#include "viterbi/x86/viterbi_decoder_sse_u16.h"

constexpr size_t K = 5;
constexpr size_t R = 4;

class ViterbiCodec {
public:
ViterbiCodec(){};
[[nodiscard]] std::vector<uint8_t> Decode(const std::vector<int8_t>& bits) const;
[[nodiscard]] std::vector<uint8_t> Decode(const std::vector<int16_t>& bits) const;

private:
const std::vector<uint8_t> G = {19, 29, 23, 27};

const int8_t soft_decision_high = +1;
const int8_t soft_decision_low = -1;
const uint8_t max_error = uint8_t(soft_decision_high - soft_decision_low) * uint8_t(R);
const uint8_t error_margin = max_error * uint8_t(3u);
const int16_t soft_decision_high = +1;
const int16_t soft_decision_low = -1;
const uint16_t max_error = uint16_t(soft_decision_high - soft_decision_low) * uint16_t(R);
const uint16_t error_margin = max_error * uint16_t(3u);

ViterbiDecoder_Config<uint8_t> config = {
const ViterbiDecoder_Config<uint16_t> config = {
.soft_decision_max_error = max_error,
.initial_start_error = std::numeric_limits<uint8_t>::min(),
.initial_non_start_error = static_cast<uint8_t>(std::numeric_limits<uint8_t>::min() + error_margin),
.renormalisation_threshold = static_cast<uint8_t>(std::numeric_limits<uint8_t>::max() - error_margin)};
.initial_start_error = std::numeric_limits<uint16_t>::min(),
.initial_non_start_error = static_cast<uint16_t>(std::numeric_limits<uint16_t>::min() + error_margin),
.renormalisation_threshold = static_cast<uint16_t>(std::numeric_limits<uint16_t>::max() - error_margin)};

ViterbiBranchTable<K, R, int8_t> branch_table =
ViterbiBranchTable<K, R, int8_t>(G.data(), soft_decision_high, soft_decision_low);
const ViterbiBranchTable<K, R, int16_t> branch_table =
ViterbiBranchTable<K, R, int16_t>(G.data(), soft_decision_high, soft_decision_low);
};
2 changes: 1 addition & 1 deletion lib/ViterbiDecoderCpp
13 changes: 7 additions & 6 deletions src/examples/tetra_viterbi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ std::vector<uint8_t> new_viterbi_decode(const std::vector<int8_t>& bits, std::si

auto config = get_hard8_decoding_config(R);
auto branch_table = ViterbiBranchTable<K, R, int8_t>(G.data(), config.soft_decision_high, config.soft_decision_low);
auto vitdec = std::make_unique<ViterbiDecoder_Scalar<K, R, uint8_t, int8_t>>(branch_table, config.decoder_config);
auto vitdec = ViterbiDecoder_Core<K, R, uint8_t, int8_t>(branch_table, config.decoder_config);
using Decoder = ViterbiDecoder_Scalar<K, R, uint8_t, int8_t>;

const size_t total_bits = bits.size() / R;
const size_t total_tail_bits = K - 1u;
Expand All @@ -90,12 +91,12 @@ std::vector<uint8_t> new_viterbi_decode(const std::vector<int8_t>& bits, std::si
std::vector<uint8_t> output_bytes;
output_bytes.resize(total_bits / 8);

vitdec->set_traceback_length(total_data_bits);
vitdec.set_traceback_length(total_data_bits);

vitdec->reset();
vitdec->update(bits.data(), bits.size());
vitdec->chainback(output_bytes.data(), total_data_bits, end_state);
const uint64_t error = vitdec->get_error();
vitdec.reset();
Decoder::template update<uint64_t>(vitdec, bits.data(), bits.size());
vitdec.chainback(output_bytes.data(), total_data_bits, end_state);
const uint64_t error = vitdec.get_error();
std::cout << "error=" << error << std::endl;

return output_bytes;
Expand Down
8 changes: 4 additions & 4 deletions src/l2/lower_mac_coding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ auto LowerMac::deinterleave(const std::vector<uint8_t>& data, const uint32_t K,
* @brief Depuncture with 2/3 rate - 8.2.3.1.3
*
*/
auto LowerMac::depuncture23(const std::vector<uint8_t>& data, const uint32_t len) noexcept -> std::vector<int8_t> {
auto LowerMac::depuncture23(const std::vector<uint8_t>& data, const uint32_t len) noexcept -> std::vector<int16_t> {
const uint8_t P[] = {0, 1, 2, 5}; // 8.2.3.1.3 - P[1..t]
std::vector<int8_t> res(4 * len * 2 / 3,
0); // 8.2.3.1.2 with flag 0 for erase bit in Viterbi routine
std::vector<int16_t> res(4 * len * 2 / 3,
0); // 8.2.3.1.2 with flag 0 for erase bit in Viterbi routine

uint8_t t = 3; // 8.2.3.1.3
uint8_t period = 8; // 8.2.3.1.2
Expand All @@ -90,7 +90,7 @@ auto LowerMac::depuncture23(const std::vector<uint8_t>& data, const uint32_t len
*
*/

auto LowerMac::viter_bi_decode_1614(const std::vector<int8_t>& data) noexcept -> std::vector<uint8_t> {
auto LowerMac::viter_bi_decode_1614(const std::vector<int16_t>& data) noexcept -> std::vector<uint8_t> {
std::vector<std::uint8_t> out{};
for (auto elem : viter_bi_codec_1614_->Decode(data)) {
for (auto i = 0; i < 8; i++) {
Expand Down
7 changes: 4 additions & 3 deletions src/utils/viter_bi_codec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@

#include <utils/viter_bi_codec.hpp>

std::vector<uint8_t> ViterbiCodec::Decode(const std::vector<int8_t>& bits) const {
auto vitdec = ViterbiDecoder_Scalar<K, R, uint8_t, int8_t>(branch_table, config);
std::vector<uint8_t> ViterbiCodec::Decode(const std::vector<int16_t>& bits) const {
auto vitdec = ViterbiDecoder_Core<K, R, uint16_t, int16_t>(branch_table, config);
using Decoder = ViterbiDecoder_SSE_u16<K, R>;

const size_t total_bits = bits.size() / R;
const size_t total_tail_bits = K - 1u;
Expand All @@ -21,7 +22,7 @@ std::vector<uint8_t> ViterbiCodec::Decode(const std::vector<int8_t>& bits) const
vitdec.set_traceback_length(total_data_bits);

vitdec.reset();
vitdec.update(bits.data(), bits.size());
Decoder::template update<uint64_t>(vitdec, bits.data(), bits.size());
vitdec.chainback(output_bytes.data(), total_data_bits, 0);
const uint64_t error = vitdec.get_error();
// std::cout << "error=" << error << std::endl;
Expand Down

0 comments on commit 0760983

Please sign in to comment.