From 25255802f12ee4a6bf7e51555d61b44c0019def7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camille=20Moni=C3=A8re?= Date: Mon, 25 Apr 2022 11:43:31 +0200 Subject: [PATCH] Remove indetermination and patch for Xilinx v2019.1 compatibility - Use of `rom_cordic_rotate` namespace to isolate functions and variables. Useful when CORDICS are included in super project. - Add define barrier to exclude some code when used when Xilinx v2019.1, especially C++11/14 code that are not fully supported by the (crazy) old version of GCC in use (v4.6.3). Need the definition of `XILINX_MAJOR` (can be done using `set XILINX_MAJOR [expr {int( [version -short] )}]` in a Xilinx TCL script and then adding it to the cflags using the `-cflags` switch with `-DXILINX_MAJOR=${XILINX_MAJOR}` or by manually adding the major version to the CFLAGS in gui. - Add a template version of the helper function, to support v2019.1. --- .../RomGeneratorConst/RomGeneratorConst.hpp | 20 ++++++----- .../sources/RomGeneratorML/RomGeneratorML.hpp | 10 +++--- .../{ => RomRotateCommon}/definitions.hpp | 36 +++++++++++++++++-- .../CCordicRotateConstexpr.hpp | 4 ++- .../CCordicRotateRom/CCordicRotateRom.hpp.in | 9 +++-- 5 files changed, 59 insertions(+), 20 deletions(-) rename RomGenerators/sources/{ => RomRotateCommon}/definitions.hpp (65%) diff --git a/RomGenerators/sources/RomGeneratorConst/RomGeneratorConst.hpp b/RomGenerators/sources/RomGeneratorConst/RomGeneratorConst.hpp index 50cd8ef..7d5ff45 100644 --- a/RomGenerators/sources/RomGeneratorConst/RomGeneratorConst.hpp +++ b/RomGenerators/sources/RomGeneratorConst/RomGeneratorConst.hpp @@ -28,21 +28,23 @@ #include -#include "definitions.hpp" +#include "RomRotateCommon/definitions.hpp" + +namespace rcr = rom_cordic_rotate; template class CRomGeneratorConst { static_assert(In_W > 0, "Inputs can't be on zero bits."); static_assert(NStages < 8, "7 stages of CORDIC is the maximum supported."); static_assert(NStages > 1, "2 stages of CORDIC is the minimum."); - static_assert(is_pow_2(divider), "divider must be a power of 2."); + static_assert(rcr::is_pow_2(), "divider must be a power of 2."); public: - static constexpr double rotation = pi / divider; + static constexpr double rotation = rcr::pi / divider; static constexpr double q = Tq; static constexpr unsigned max_length = 2 * divider * Tq; // 2pi / (pi / divider) * q - static constexpr unsigned addr_length = needed_bits(max_length - 1); + static constexpr unsigned addr_length = rcr::needed_bits(); static constexpr int64_t scale_factor = int64_t(1U << (In_W - 1)); static constexpr double atanDbl[28] { @@ -68,18 +70,18 @@ private: #if 0 printf("Step 0 - %03u : %02x : %8lf\n", R, R, beta); #endif - if ((beta < -two_pi) || (two_pi <= beta)) { + if ((beta < -rcr::two_pi) || (rcr::two_pi <= beta)) { fprintf(stderr, "rotation must be inside ] -2*pi; 2*pi ]"); exit(EXIT_FAILURE); } - if ((beta <= -pi) || (beta > pi)) { - beta = beta < 0. ? beta + two_pi : beta - two_pi; + if ((beta <= -rcr::pi) || (beta > rcr::pi)) { + beta = beta < 0. ? beta + rcr::two_pi : beta - rcr::two_pi; } - if ((beta < -half_pi) || (beta > half_pi)) { + if ((beta < -rcr::half_pi) || (beta > rcr::half_pi)) { R = R | sig_mask; - beta = beta < 0 ? beta + pi : beta - pi; + beta = beta < 0 ? beta + rcr::pi : beta - rcr::pi; // A = -A; // B = -B; } else { diff --git a/RomGenerators/sources/RomGeneratorML/RomGeneratorML.hpp b/RomGenerators/sources/RomGeneratorML/RomGeneratorML.hpp index 8d48594..be9fb80 100644 --- a/RomGenerators/sources/RomGeneratorML/RomGeneratorML.hpp +++ b/RomGenerators/sources/RomGeneratorML/RomGeneratorML.hpp @@ -25,7 +25,9 @@ #include #include -#include "definitions.hpp" +#include "RomRotateCommon/definitions.hpp" + +namespace rcr = rom_cordic_rotate; template class CRomGeneratorML { @@ -33,14 +35,14 @@ class CRomGeneratorML { static_assert(NStages < 8, "7 stages of CORDIC is the maximum supported."); static_assert(NStages > 1, "2 stages of CORDIC is the minimum."); static_assert(NStages > 1, "2 stages of CORDIC is the minimum."); - static_assert(is_pow_2(divider), "divider must be a power of 2."); + static_assert(rcr::is_pow_2(), "divider must be a power of 2."); public: - static constexpr double rotation = pi / divider; + static constexpr double rotation = rcr::pi / divider; static constexpr double q = Tq; static constexpr unsigned max_length = 2 * divider * Tq; // 2pi / (pi / divider) * q - static constexpr unsigned addr_length = needed_bits(max_length - 1); + static constexpr unsigned addr_length = rcr::needed_bits(); static constexpr int64_t scale_factor = int64_t(1U << (In_W - 1)); private: diff --git a/RomGenerators/sources/definitions.hpp b/RomGenerators/sources/RomRotateCommon/definitions.hpp similarity index 65% rename from RomGenerators/sources/definitions.hpp rename to RomGenerators/sources/RomRotateCommon/definitions.hpp index cbf429b..1575ca8 100644 --- a/RomGenerators/sources/definitions.hpp +++ b/RomGenerators/sources/RomRotateCommon/definitions.hpp @@ -17,12 +17,14 @@ * */ -#ifndef _DEFINITIONS_HPP_ -#define _DEFINITIONS_HPP_ +#ifndef _ROMCORDIC_DEFINITIONS_HPP_ +#define _ROMCORDIC_DEFINITIONS_HPP_ #include #include +namespace rom_cordic_rotate { + #ifdef M_PI constexpr double pi = M_PI; #else @@ -34,6 +36,8 @@ constexpr double inv_pi = 1 / pi; constexpr double two_pi = 2 * pi; constexpr double inv_2pi = 0.5 * inv_pi; +#if XILINX_MAJOR > 2019 || !defined (XILINX_MAJOR) + constexpr uint32_t needed_bits(uint32_t value) { uint32_t result = 0; while (value > 0) { @@ -47,4 +51,30 @@ constexpr bool is_pow_2(uint32_t value) { return (1U << (needed_bits(value) - 1)) == value; } -#endif // _DEFINITIONS_HPP_ +#endif + +template +constexpr uint32_t needed_bits() { return needed_bits<(value >> 1)>() + 1; } + +template <> +constexpr uint32_t needed_bits<0>() { return 0; } + +template <> +constexpr uint32_t needed_bits<1>() { return 1; } + +template <> +constexpr uint32_t needed_bits<2>() { return 2; } + +template +constexpr bool is_pow_2() { + return (1U << (needed_bits() - 1)) == value; +} + +template <> +constexpr bool is_pow_2<0>() { + return false; +} + +} // namespace rom_cordic_rotate + +#endif // _ROMCORDIC_DEFINITIONS_HPP_ diff --git a/sources/CCordicRotateConstexpr/CCordicRotateConstexpr.hpp b/sources/CCordicRotateConstexpr/CCordicRotateConstexpr.hpp index 4b9ad36..f6c69af 100644 --- a/sources/CCordicRotateConstexpr/CCordicRotateConstexpr.hpp +++ b/sources/CCordicRotateConstexpr/CCordicRotateConstexpr.hpp @@ -32,12 +32,14 @@ #include "RomGeneratorConst/RomGeneratorConst.hpp" +namespace rcr = rom_cordic_rotate; + template class CCordicRotateConstexpr { static_assert(TIn_W > 0, "Inputs can't be on zero bits."); static_assert(Tnb_stages < 8, "7 stages of CORDIC is the maximum supported."); static_assert(Tnb_stages > 1, "2 stages of CORDIC is the minimum."); - static_assert(is_pow_2(divider), "divider must be a power of 2."); + static_assert(rcr::is_pow_2(), "divider must be a power of 2."); public: // ``` GNU Octave diff --git a/sources/CCordicRotateRom/CCordicRotateRom.hpp.in b/sources/CCordicRotateRom/CCordicRotateRom.hpp.in index 059ab99..b6af7c2 100644 --- a/sources/CCordicRotateRom/CCordicRotateRom.hpp.in +++ b/sources/CCordicRotateRom/CCordicRotateRom.hpp.in @@ -32,7 +32,10 @@ #include "CCordicRotateRomTemplate.hpp" #include "CordicRoms/cordic_rom_@ROM_TYPE@_@CORDIC_W@_@CORDIC_STAGES@_@CORDIC_Q@_@CORDIC_DIVIDER@.hpp" -#include "definitions.hpp" +#include "RomRotateCommon/definitions.hpp" + + +namespace rcr = rom_cordic_rotate; #ifndef KN_STATIC_TABLE_DEFINED #define KN_STATIC_TABLE_DEFINED 1 @@ -49,7 +52,7 @@ class CCordicRotateRom 0, "Inputs can't be on zero bits."); static_assert(@CORDIC_STAGES@ < 8, "7 stages of CORDIC is the maximum supported."); static_assert(@CORDIC_STAGES@ > 1, "2 stages of CORDIC is the minimum."); - static_assert(is_pow_2(@CORDIC_DIVIDER@), "divider must be a power of 2."); + static_assert(rcr::is_pow_2<@CORDIC_DIVIDER@>(), "divider must be a power of 2."); public: static constexpr unsigned In_W = @CORDIC_W@; @@ -63,7 +66,7 @@ public: static constexpr uint64_t in_scale_factor = uint64_t(1U << (In_W - In_I)); static constexpr uint64_t out_scale_factor = uint64_t(1U << (Out_W - Out_I)); - static constexpr double rotation = pi / @CORDIC_DIVIDER@; + static constexpr double rotation = rcr::pi / @CORDIC_DIVIDER@; static constexpr unsigned addr_length = cordic_roms::@ROM_TYPE@_@CORDIC_W@_@CORDIC_STAGES@_@CORDIC_Q@_@CORDIC_DIVIDER@_size; static constexpr int64_t scale_cordic(int64_t in) {