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 "definitions.hpp"
#include "RomRotateCommon/definitions.hpp"
namespace rcr = rom_cordic_rotate;
template <unsigned In_W, unsigned NStages, unsigned Tq, unsigned divider = 2>
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>(), "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<max_length - 1>();
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 {

View file

@ -25,7 +25,9 @@
#include <complex>
#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>
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>(), "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<max_length - 1>();
static constexpr int64_t scale_factor = int64_t(1U << (In_W - 1));
private:

View file

@ -17,12 +17,14 @@
*
*/
#ifndef _DEFINITIONS_HPP_
#define _DEFINITIONS_HPP_
#ifndef _ROMCORDIC_DEFINITIONS_HPP_
#define _ROMCORDIC_DEFINITIONS_HPP_
#include <cstddef>
#include <cstdint>
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 <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"
namespace rcr = rom_cordic_rotate;
template <unsigned TIn_W, unsigned TIn_I, unsigned Tnb_stages, unsigned Tq, unsigned divider = 2>
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>(), "divider must be a power of 2.");
public:
// ``` GNU Octave

View file

@ -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<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_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) {