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.
This commit is contained in:
Camille Monière 2022-04-25 11:43:31 +02:00
parent a0ce4ceab0
commit 25255802f1
Signed by: moniere
GPG key ID: 188DD5B072181C0F
5 changed files with 59 additions and 20 deletions

View file

@ -28,21 +28,23 @@
#include <cassert> #include <cassert>
#include "definitions.hpp" #include "RomRotateCommon/definitions.hpp"
namespace rcr = rom_cordic_rotate;
template <unsigned In_W, unsigned NStages, unsigned Tq, unsigned divider = 2> template <unsigned In_W, unsigned NStages, unsigned Tq, unsigned divider = 2>
class CRomGeneratorConst { class CRomGeneratorConst {
static_assert(In_W > 0, "Inputs can't be on zero bits."); 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 < 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>(), "divider must be a power of 2.");
public: public:
static constexpr double rotation = pi / divider; static constexpr double rotation = rcr::pi / divider;
static constexpr double q = Tq; static constexpr double q = Tq;
static constexpr unsigned max_length = 2 * divider * Tq; // 2pi / (pi / divider) * q 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<max_length - 1>();
static constexpr int64_t scale_factor = int64_t(1U << (In_W - 1)); static constexpr int64_t scale_factor = int64_t(1U << (In_W - 1));
static constexpr double atanDbl[28] { static constexpr double atanDbl[28] {
@ -68,18 +70,18 @@ private:
#if 0 #if 0
printf("Step 0 - %03u : %02x : %8lf\n", R, R, beta); printf("Step 0 - %03u : %02x : %8lf\n", R, R, beta);
#endif #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 ]"); fprintf(stderr, "rotation must be inside ] -2*pi; 2*pi ]");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if ((beta <= -pi) || (beta > pi)) { if ((beta <= -rcr::pi) || (beta > rcr::pi)) {
beta = beta < 0. ? beta + two_pi : beta - two_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; R = R | sig_mask;
beta = beta < 0 ? beta + pi : beta - pi; beta = beta < 0 ? beta + rcr::pi : beta - rcr::pi;
// A = -A; // A = -A;
// B = -B; // B = -B;
} else { } else {

View file

@ -25,7 +25,9 @@
#include <complex> #include <complex>
#include <cstdint> #include <cstdint>
#include "definitions.hpp" #include "RomRotateCommon/definitions.hpp"
namespace rcr = rom_cordic_rotate;
template <unsigned In_W, unsigned NStages, unsigned Tq, unsigned divider = 2> template <unsigned In_W, unsigned NStages, unsigned Tq, unsigned divider = 2>
class CRomGeneratorML { class CRomGeneratorML {
@ -33,14 +35,14 @@ class CRomGeneratorML {
static_assert(NStages < 8, "7 stages of CORDIC is the maximum supported."); 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(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>(), "divider must be a power of 2.");
public: public:
static constexpr double rotation = pi / divider; static constexpr double rotation = rcr::pi / divider;
static constexpr double q = Tq; static constexpr double q = Tq;
static constexpr unsigned max_length = 2 * divider * Tq; // 2pi / (pi / divider) * q 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<max_length - 1>();
static constexpr int64_t scale_factor = int64_t(1U << (In_W - 1)); static constexpr int64_t scale_factor = int64_t(1U << (In_W - 1));
private: private:

View file

@ -17,12 +17,14 @@
* *
*/ */
#ifndef _DEFINITIONS_HPP_ #ifndef _ROMCORDIC_DEFINITIONS_HPP_
#define _DEFINITIONS_HPP_ #define _ROMCORDIC_DEFINITIONS_HPP_
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
namespace rom_cordic_rotate {
#ifdef M_PI #ifdef M_PI
constexpr double pi = M_PI; constexpr double pi = M_PI;
#else #else
@ -34,6 +36,8 @@ constexpr double inv_pi = 1 / pi;
constexpr double two_pi = 2 * pi; constexpr double two_pi = 2 * pi;
constexpr double inv_2pi = 0.5 * inv_pi; constexpr double inv_2pi = 0.5 * inv_pi;
#if XILINX_MAJOR > 2019 || !defined (XILINX_MAJOR)
constexpr uint32_t needed_bits(uint32_t value) { constexpr uint32_t needed_bits(uint32_t value) {
uint32_t result = 0; uint32_t result = 0;
while (value > 0) { while (value > 0) {
@ -47,4 +51,30 @@ constexpr bool is_pow_2(uint32_t value) {
return (1U << (needed_bits(value) - 1)) == value; return (1U << (needed_bits(value) - 1)) == value;
} }
#endif // _DEFINITIONS_HPP_ #endif
template <uint32_t value>
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 <uint32_t value>
constexpr bool is_pow_2() {
return (1U << (needed_bits<value>() - 1)) == value;
}
template <>
constexpr bool is_pow_2<0>() {
return false;
}
} // namespace rom_cordic_rotate
#endif // _ROMCORDIC_DEFINITIONS_HPP_

View file

@ -32,12 +32,14 @@
#include "RomGeneratorConst/RomGeneratorConst.hpp" #include "RomGeneratorConst/RomGeneratorConst.hpp"
namespace rcr = rom_cordic_rotate;
template <unsigned TIn_W, unsigned TIn_I, unsigned Tnb_stages, unsigned Tq, unsigned divider = 2> template <unsigned TIn_W, unsigned TIn_I, unsigned Tnb_stages, unsigned Tq, unsigned divider = 2>
class CCordicRotateConstexpr { class CCordicRotateConstexpr {
static_assert(TIn_W > 0, "Inputs can't be on zero bits."); 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 < 8, "7 stages of CORDIC is the maximum supported.");
static_assert(Tnb_stages > 1, "2 stages of CORDIC is the minimum."); 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>(), "divider must be a power of 2.");
public: public:
// ``` GNU Octave // ``` GNU Octave

View file

@ -32,7 +32,10 @@
#include "CCordicRotateRomTemplate.hpp" #include "CCordicRotateRomTemplate.hpp"
#include "CordicRoms/cordic_rom_@ROM_TYPE@_@CORDIC_W@_@CORDIC_STAGES@_@CORDIC_Q@_@CORDIC_DIVIDER@.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 #ifndef KN_STATIC_TABLE_DEFINED
#define KN_STATIC_TABLE_DEFINED 1 #define KN_STATIC_TABLE_DEFINED 1
@ -49,7 +52,7 @@ class CCordicRotateRom<TIn_I, @ROM_TYPE@, @CORDIC_W@, @CORDIC_STAGES@, @CORDIC_Q
static_assert(@CORDIC_W@ > 0, "Inputs can't be on zero bits."); static_assert(@CORDIC_W@ > 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@ < 8, "7 stages of CORDIC is the maximum supported.");
static_assert(@CORDIC_STAGES@ > 1, "2 stages of CORDIC is the minimum."); 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: public:
static constexpr unsigned In_W = @CORDIC_W@; 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 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 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 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) { static constexpr int64_t scale_cordic(int64_t in) {