diff --git a/soc/st/arm/m0/l0 b/soc/st/arm/m0/l0 index 21155ba..55293d0 160000 --- a/soc/st/arm/m0/l0 +++ b/soc/st/arm/m0/l0 @@ -1 +1 @@ -Subproject commit 21155bace56d238a293151d32caaea343ebdb7cc +Subproject commit 55293d08e19ddc22bafff1ff9f9ed11df5ae2243 diff --git a/xmcu/look_up_tables.hpp b/xmcu/look_up_tables.hpp new file mode 100644 index 0000000..ee8c859 --- /dev/null +++ b/xmcu/look_up_tables.hpp @@ -0,0 +1,206 @@ +#pragma once + +/* + * Copyright (c) xEmbeddedTools team and contributors. + * Licensed under the Apache License, Version 2.0. See LICENSE file in the project root for details. + */ + +// std +#include +// #include +// #include +// #include +#include +// #include + +namespace xmcu::look_up_tables { + +#define concept_allowed 1 +#if concept_allowed + +template +concept is_row = requires(const T a) { + typename T::value_type; + typename T::containter_type; + a.size(); +} && requires(T a, T b) { + { a |= b }; +}; + +template +concept is_desc = is_row && requires { + typename T::destination_type; + typename T::reduced_type<1>; +}; +template +concept is_Input_table = requires { + typename T::value_type; + typename T::containter_type; + { T::decode_state(0) } -> std::convertible_to; +} && xmcu::look_up_tables::is_desc && requires(const T& a) { + a.size(); + a.lut_out(0); +}; +#else +#define is_row typename +#define is_desc typename +#define is_Input_table typename +#endif + +template class Row : public std::array +{ +public: + using containter_type = std::array; + consteval containter_type& as_array() + { + return *this; + } + // operators + constexpr Row& operator|=(const Row& a_rhs) + { + auto& ref_this = *this; + + for (std::size_t i = 0; i < this->size(); ++i) + { + ref_this[i] |= a_rhs[i]; + } + return ref_this; + } + constexpr Row operator|(const Row& a_rhs) const + { + auto ref_this = *this; + + for (std::size_t i = 0; i < this->size(); ++i) + { + ref_this[i] |= a_rhs[i]; + } + return ref_this; + } +}; + +// single row +template class Input_row // might be join with row + : public Row +{ +public: + using destination_type = Row; + template using reduced_type = Input_row; +}; + +namespace decoders { +struct Direct +{ + consteval static std::size_t decode(std::size_t a_value) + { + return a_value; + } +}; +template struct Offset +{ + consteval static std::size_t decode(std::size_t a_value) + { + return a_value + OFFSET; + } +}; +template struct Offset_Mask +{ + consteval static std::size_t decode(std::size_t a_value) + { + return MASK & (a_value + OFFSET); + } +}; +} // namespace decoders + +template class Input_table : public std::array +{ +public: + // introduced for local usage only (`lut_out`) + using destination_type = typename T::destination_type; + using containter_type = std::array; + consteval Input_table(const std::array& a_table, Decoder = {}) + : std::array { a_table } + { + } + consteval static std::size_t decode_state(std::size_t a_state) + { + return Decoder::decode(a_state); + } + consteval auto lut_out(std::size_t a_index) const + { + auto binary = decode_state(a_index); + auto result = destination_type {}; + for (std::size_t i = 0; i < this->size(); ++i) + { + if (0 == (binary & 1u << i)) + { + continue; + } + result |= (*this)[i]; + } + return result; + } +}; + +template class Table + : public std::array +{ +public: + using desc_type = T; + static constexpr std::size_t output_words_count = BITS; + + template +#if concept_allowed + requires(N_dest < output_words_count && N_dest > 0) +#endif + consteval Table, BITS> + extract_words(const std::array& a_columns) const + { + static_assert(N_dest < output_words_count && N_dest > 0, + "N_dest should be in range [0 - LUT output word size]"); + using Row = typename T::reduced_type; + Table result; + + for (std::size_t i = 0; i < N; ++i) + { + Row line {}; + const auto& source_line = this->at(i); + for (std::size_t word = 0; word < a_columns.size(); ++word) + { + line[word] = source_line.at(a_columns[word]); + } + result[i] = line; + } + + return result; + } + consteval Table operator|(const Table& a_rhs) const + { + Table result; + for (std::size_t i = 0; i < N; ++i) + { + result[i] = (*this)[i] | a_rhs[i]; + } + + return result; + } +}; + +template +consteval auto compose_table_from_bitlist(const I& a_description, const Table& input_table) +{ + auto result_array { input_table }; + for (std::size_t channel = 0; channel < result_array.size(); ++channel) + { + result_array.at(channel) |= a_description.lut_out(channel); + } + return result_array; +} + +template +consteval auto compose_table_from_bitlist(const std::array& a_description) +{ + const std::array input_table = std::array {}; + return compose_table_from_bitlist(a_description, input_table); +} + +} // namespace xmcu::look_up_tables