mirror of
https://github.com/DrasLorus/CORDIC_Rotate_APFX.git
synced 2024-11-22 04:33:17 +01:00
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:
parent
a0ce4ceab0
commit
25255802f1
5 changed files with 59 additions and 20 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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_
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue