mirror of
https://github.com/DrasLorus/CORDIC_Rotate_APFX.git
synced 2024-11-24 05:33:16 +01:00
Road to template cordic rotate
This commit is contained in:
parent
fcffa1cb7c
commit
d46fbc40b6
9 changed files with 400238 additions and 154 deletions
|
@ -60,5 +60,13 @@ if ((NOT EXISTS ${AP_INCLUDE_DIR}/ap_int.h) OR (NOT EXISTS
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_library (cordic STATIC sources/CCordicRotate/CCordicRotate.cpp)
|
add_library (cordic STATIC sources/CCordicRotate/CCordicRotate.cpp)
|
||||||
|
target_include_directories (cordic PUBLIC sources)
|
||||||
target_include_directories (cordic SYSTEM PUBLIC ${AP_INCLUDE_DIR})
|
target_include_directories (cordic SYSTEM PUBLIC ${AP_INCLUDE_DIR})
|
||||||
|
|
||||||
|
find_package(Catch2 REQUIRED)
|
||||||
|
|
||||||
|
add_library (catch_common OBJECT sources/tb/main_catch2.cpp)
|
||||||
|
target_link_libraries(catch_common PUBLIC Catch2::Catch2)
|
||||||
|
|
||||||
|
add_executable(cordic_tb sources/tb/cordic_tb.cpp)
|
||||||
|
target_link_libraries(cordic_tb PUBLIC cordic catch_common)
|
||||||
|
|
100000
data/input.dat
Normal file
100000
data/input.dat
Normal file
File diff suppressed because it is too large
Load diff
100000
data/input_8_14_10_17_5_19_12_12.dat
Normal file
100000
data/input_8_14_10_17_5_19_12_12.dat
Normal file
File diff suppressed because it is too large
Load diff
100000
data/output.dat
Normal file
100000
data/output.dat
Normal file
File diff suppressed because it is too large
Load diff
100000
data/output_8_14_10_17_5_19_12_12.dat
Normal file
100000
data/output_8_14_10_17_5_19_12_12.dat
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1 +1,153 @@
|
||||||
#include "CCordicRotate.hpp"
|
#include "CCordicRotate.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#define uint2int(sz, in) ((in & (1U << sz)) == (1U << sz) \
|
||||||
|
? static_cast<short>(~in + 1) \
|
||||||
|
: static_cast<short>(in))
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void CCordicRotate<8, 14, 4, 17, 5, 19, 7, 12>::process(
|
||||||
|
const ap_fixed<14, 4> & fx_angle,
|
||||||
|
const ap_fixed<17, 5> & fx_re_in,
|
||||||
|
const ap_fixed<17, 5> & fx_im_in,
|
||||||
|
ap_fixed<19, 7> & fx_re_out,
|
||||||
|
ap_fixed<19, 7> & fx_im_out) {
|
||||||
|
|
||||||
|
constexpr uint64_t sign_mask_14 = 0x2000; // 0bxxx xx10 0000 0000 0000
|
||||||
|
constexpr uint64_t sign_mask_17 = 0x10000; // 0bxx1 0000 0000 0000 0000
|
||||||
|
constexpr uint64_t sign_mask_19 = 0x10000; // 0b100 0000 0000 0000 0000
|
||||||
|
|
||||||
|
const uint16_t angle_bits = fx_angle.bits_to_uint64();
|
||||||
|
|
||||||
|
const short angle = uint2int(14, angle_bits);
|
||||||
|
|
||||||
|
const uint32_t re_in_bits = fx_re_in.bits_to_uint64();
|
||||||
|
const uint32_t im_in_bits = fx_im_in.bits_to_uint64();
|
||||||
|
|
||||||
|
const std::complex<int32_t> value(uint2int(17, re_in_bits), uint2int(17, im_in_bits));
|
||||||
|
|
||||||
|
int b_yn;
|
||||||
|
int xn;
|
||||||
|
int xtmp;
|
||||||
|
int ytmp;
|
||||||
|
short z;
|
||||||
|
bool negate;
|
||||||
|
if (angle > 1608) {
|
||||||
|
if (((angle - 3217) & 8192) != 0) {
|
||||||
|
z = static_cast<short>((angle - 3217) | -8192);
|
||||||
|
} else {
|
||||||
|
z = static_cast<short>((angle - 3217) & 8191);
|
||||||
|
}
|
||||||
|
if (z <= 1608) {
|
||||||
|
negate = true;
|
||||||
|
} else {
|
||||||
|
if (((angle - 6434) & 8192) != 0) {
|
||||||
|
z = static_cast<short>((angle - 6434) | -8192);
|
||||||
|
} else {
|
||||||
|
z = static_cast<short>((angle - 6434) & 8191);
|
||||||
|
}
|
||||||
|
negate = false;
|
||||||
|
}
|
||||||
|
} else if (angle < -1608) {
|
||||||
|
if (((angle + 3217) & 8192) != 0) {
|
||||||
|
z = static_cast<short>((angle + 3217) | -8192);
|
||||||
|
} else {
|
||||||
|
z = static_cast<short>((angle + 3217) & 8191);
|
||||||
|
}
|
||||||
|
if (z >= -1608) {
|
||||||
|
negate = true;
|
||||||
|
} else {
|
||||||
|
if (((angle + 6434) & 8192) != 0) {
|
||||||
|
z = static_cast<short>((angle + 6434) | -8192);
|
||||||
|
} else {
|
||||||
|
z = static_cast<short>((angle + 6434) & 8191);
|
||||||
|
}
|
||||||
|
negate = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
z = angle;
|
||||||
|
negate = false;
|
||||||
|
}
|
||||||
|
z = static_cast<short>(z << 2);
|
||||||
|
if ((z & 8192) != 0) {
|
||||||
|
z = static_cast<short>(z | -8192);
|
||||||
|
} else {
|
||||||
|
z = static_cast<short>(z & 8191);
|
||||||
|
}
|
||||||
|
xn = value.real();
|
||||||
|
b_yn = value.imag();
|
||||||
|
xtmp = value.real();
|
||||||
|
ytmp = value.imag();
|
||||||
|
for (int idx = 0; idx < 8; idx++) {
|
||||||
|
if (z < 0) {
|
||||||
|
z = static_cast<short>(z + atanLUT.table[idx]);
|
||||||
|
if ((z & 8192) != 0) {
|
||||||
|
z = static_cast<short>(z | -8192);
|
||||||
|
} else {
|
||||||
|
z = static_cast<short>(z & 8191);
|
||||||
|
}
|
||||||
|
ytmp += xn;
|
||||||
|
if ((ytmp & 262144) != 0) {
|
||||||
|
xn = ytmp | -262144;
|
||||||
|
} else {
|
||||||
|
xn = ytmp & 262143;
|
||||||
|
}
|
||||||
|
ytmp = b_yn - xtmp;
|
||||||
|
if ((ytmp & 262144) != 0) {
|
||||||
|
b_yn = ytmp | -262144;
|
||||||
|
} else {
|
||||||
|
b_yn = ytmp & 262143;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
z = static_cast<short>(z - atanLUT.table[idx]);
|
||||||
|
if ((z & 8192) != 0) {
|
||||||
|
z = static_cast<short>(z | -8192);
|
||||||
|
} else {
|
||||||
|
z = static_cast<short>(z & 8191);
|
||||||
|
}
|
||||||
|
ytmp = xn - ytmp;
|
||||||
|
if ((ytmp & 262144) != 0) {
|
||||||
|
xn = ytmp | -262144;
|
||||||
|
} else {
|
||||||
|
xn = ytmp & 262143;
|
||||||
|
}
|
||||||
|
ytmp = b_yn + xtmp;
|
||||||
|
if ((ytmp & 262144) != 0) {
|
||||||
|
b_yn = ytmp | -262144;
|
||||||
|
} else {
|
||||||
|
b_yn = ytmp & 262143;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ytmp = xn >> (idx + 1);
|
||||||
|
if ((ytmp & 262144) != 0) {
|
||||||
|
xtmp = ytmp | -262144;
|
||||||
|
} else {
|
||||||
|
xtmp = ytmp & 262143;
|
||||||
|
}
|
||||||
|
ytmp = b_yn >> (idx + 1);
|
||||||
|
if ((ytmp & 262144) != 0) {
|
||||||
|
ytmp |= -262144;
|
||||||
|
} else {
|
||||||
|
ytmp &= 262143;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (negate) {
|
||||||
|
if ((-xn & 262144) != 0) {
|
||||||
|
xn = -xn | -262144;
|
||||||
|
} else {
|
||||||
|
xn = -xn & 262143;
|
||||||
|
}
|
||||||
|
if ((-b_yn & 262144) != 0) {
|
||||||
|
b_yn = -b_yn | -262144;
|
||||||
|
} else {
|
||||||
|
b_yn = -b_yn & 262143;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int64_t i_xn = (xn * 39797L) >> 16;
|
||||||
|
const int64_t i_b_yn = (b_yn * 39797L) >> 16;
|
||||||
|
|
||||||
|
ap_fixed<19, 7> re, im;
|
||||||
|
fx_re_out.V = *reinterpret_cast<const uint64_t *>(&i_xn);
|
||||||
|
fx_im_out.V = *reinterpret_cast<const uint64_t *>(&i_b_yn);
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef C_CORDIC_ROTATE_HPP
|
||||||
|
#define C_CORDIC_ROTATE_HPP
|
||||||
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -57,156 +60,4 @@ public:
|
||||||
virtual ~CCordicRotate() {};
|
virtual ~CCordicRotate() {};
|
||||||
};
|
};
|
||||||
|
|
||||||
#define uint2int(sz, in) ((in & (1U << sz)) == (1U << sz) \
|
#endif
|
||||||
? static_cast<short>(~in + 1) \
|
|
||||||
: static_cast<short>(in))
|
|
||||||
|
|
||||||
template <>
|
|
||||||
void CCordicRotate<8, 14, 10, 17, 5, 19, 12, 12>::process(
|
|
||||||
const ap_fixed<14, 10> & fx_angle,
|
|
||||||
const ap_fixed<17, 5> & fx_re_in,
|
|
||||||
const ap_fixed<17, 5> & fx_im_in,
|
|
||||||
ap_fixed<19, 12> & fx_re_out,
|
|
||||||
ap_fixed<19, 12> & fx_im_out) {
|
|
||||||
|
|
||||||
constexpr uint64_t sign_mask_14 = 0x2000; // 0bxxx xx10 0000 0000 0000
|
|
||||||
constexpr uint64_t sign_mask_17 = 0x10000; // 0bxx1 0000 0000 0000 0000
|
|
||||||
constexpr uint64_t sign_mask_19 = 0x10000; // 0b100 0000 0000 0000 0000
|
|
||||||
|
|
||||||
const uint16_t angle_bits = fx_angle.bits_to_uint64();
|
|
||||||
|
|
||||||
const short angle = uint2int(14, angle_bits);
|
|
||||||
|
|
||||||
const uint32_t re_in_bits = fx_re_in.bits_to_uint64();
|
|
||||||
const uint32_t im_in_bits = fx_im_in.bits_to_uint64();
|
|
||||||
|
|
||||||
const std::complex<int32_t> value(uint2int(17, re_in_bits), uint2int(17, im_in_bits));
|
|
||||||
|
|
||||||
int b_yn;
|
|
||||||
int xn;
|
|
||||||
int xtmp;
|
|
||||||
int ytmp;
|
|
||||||
short z;
|
|
||||||
bool negate;
|
|
||||||
if (angle > 1608) {
|
|
||||||
if (((angle - 3217) & 8192) != 0) {
|
|
||||||
z = static_cast<short>((angle - 3217) | -8192);
|
|
||||||
} else {
|
|
||||||
z = static_cast<short>((angle - 3217) & 8191);
|
|
||||||
}
|
|
||||||
if (z <= 1608) {
|
|
||||||
negate = true;
|
|
||||||
} else {
|
|
||||||
if (((angle - 6434) & 8192) != 0) {
|
|
||||||
z = static_cast<short>((angle - 6434) | -8192);
|
|
||||||
} else {
|
|
||||||
z = static_cast<short>((angle - 6434) & 8191);
|
|
||||||
}
|
|
||||||
negate = false;
|
|
||||||
}
|
|
||||||
} else if (angle < -1608) {
|
|
||||||
if (((angle + 3217) & 8192) != 0) {
|
|
||||||
z = static_cast<short>((angle + 3217) | -8192);
|
|
||||||
} else {
|
|
||||||
z = static_cast<short>((angle + 3217) & 8191);
|
|
||||||
}
|
|
||||||
if (z >= -1608) {
|
|
||||||
negate = true;
|
|
||||||
} else {
|
|
||||||
if (((angle + 6434) & 8192) != 0) {
|
|
||||||
z = static_cast<short>((angle + 6434) | -8192);
|
|
||||||
} else {
|
|
||||||
z = static_cast<short>((angle + 6434) & 8191);
|
|
||||||
}
|
|
||||||
negate = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
z = angle;
|
|
||||||
negate = false;
|
|
||||||
}
|
|
||||||
z = static_cast<short>(z << 2);
|
|
||||||
if ((z & 8192) != 0) {
|
|
||||||
z = static_cast<short>(z | -8192);
|
|
||||||
} else {
|
|
||||||
z = static_cast<short>(z & 8191);
|
|
||||||
}
|
|
||||||
xn = value.real();
|
|
||||||
b_yn = value.imag();
|
|
||||||
xtmp = value.real();
|
|
||||||
ytmp = value.imag();
|
|
||||||
for (int idx = 0; idx < 8; idx++) {
|
|
||||||
if (z < 0) {
|
|
||||||
z = static_cast<short>(z + atanLUT.table[idx]);
|
|
||||||
if ((z & 8192) != 0) {
|
|
||||||
z = static_cast<short>(z | -8192);
|
|
||||||
} else {
|
|
||||||
z = static_cast<short>(z & 8191);
|
|
||||||
}
|
|
||||||
ytmp += xn;
|
|
||||||
if ((ytmp & 262144) != 0) {
|
|
||||||
xn = ytmp | -262144;
|
|
||||||
} else {
|
|
||||||
xn = ytmp & 262143;
|
|
||||||
}
|
|
||||||
ytmp = b_yn - xtmp;
|
|
||||||
if ((ytmp & 262144) != 0) {
|
|
||||||
b_yn = ytmp | -262144;
|
|
||||||
} else {
|
|
||||||
b_yn = ytmp & 262143;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
z = static_cast<short>(z - atanLUT.table[idx]);
|
|
||||||
if ((z & 8192) != 0) {
|
|
||||||
z = static_cast<short>(z | -8192);
|
|
||||||
} else {
|
|
||||||
z = static_cast<short>(z & 8191);
|
|
||||||
}
|
|
||||||
ytmp = xn - ytmp;
|
|
||||||
if ((ytmp & 262144) != 0) {
|
|
||||||
xn = ytmp | -262144;
|
|
||||||
} else {
|
|
||||||
xn = ytmp & 262143;
|
|
||||||
}
|
|
||||||
ytmp = b_yn + xtmp;
|
|
||||||
if ((ytmp & 262144) != 0) {
|
|
||||||
b_yn = ytmp | -262144;
|
|
||||||
} else {
|
|
||||||
b_yn = ytmp & 262143;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ytmp = xn >> (idx + 1);
|
|
||||||
if ((ytmp & 262144) != 0) {
|
|
||||||
xtmp = ytmp | -262144;
|
|
||||||
} else {
|
|
||||||
xtmp = ytmp & 262143;
|
|
||||||
}
|
|
||||||
ytmp = b_yn >> (idx + 1);
|
|
||||||
if ((ytmp & 262144) != 0) {
|
|
||||||
ytmp |= -262144;
|
|
||||||
} else {
|
|
||||||
ytmp &= 262143;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (negate) {
|
|
||||||
if ((-xn & 262144) != 0) {
|
|
||||||
xn = -xn | -262144;
|
|
||||||
} else {
|
|
||||||
xn = -xn & 262143;
|
|
||||||
}
|
|
||||||
if ((-b_yn & 262144) != 0) {
|
|
||||||
b_yn = -b_yn | -262144;
|
|
||||||
} else {
|
|
||||||
b_yn = -b_yn & 262143;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ap_fixed<19, 7> re, im;
|
|
||||||
re.V = static_cast<uint32_t>((xn * 39797L) >> 16);
|
|
||||||
im.V = static_cast<uint32_t>((b_yn * 39797L) >> 16);
|
|
||||||
|
|
||||||
ap_fx_cpx<19, 7> iterative_factor;
|
|
||||||
iterative_factor.real(re);
|
|
||||||
iterative_factor.imag(im);
|
|
||||||
|
|
||||||
return iterative_factor;
|
|
||||||
}
|
|
||||||
|
|
71
sources/tb/cordic_tb.cpp
Normal file
71
sources/tb/cordic_tb.cpp
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#include "CCordicRotate/CCordicRotate.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
typedef CCordicRotate<8, 14, 4, 17, 5, 19, 7, 12> cordic_t;
|
||||||
|
|
||||||
|
using Catch::Matchers::Floating::WithinAbsMatcher;
|
||||||
|
|
||||||
|
TEST_CASE("_8_14_10_17_5_19_12_12") {
|
||||||
|
|
||||||
|
string input_fn = "../data/input.dat"; // _8_14_4_17_5_19_7_12
|
||||||
|
string output_fn = "../data/output.dat"; // _8_14_4_17_5_19_7_12
|
||||||
|
|
||||||
|
constexpr unsigned n_lines = 100000;
|
||||||
|
ap_fixed<17, 5> values_re_in[n_lines];
|
||||||
|
ap_fixed<17, 5> values_im_in[n_lines];
|
||||||
|
ap_fixed<14, 4> angles_in[n_lines];
|
||||||
|
ap_fixed<19, 7> values_re_out[n_lines];
|
||||||
|
ap_fixed<19, 7> values_im_out[n_lines];
|
||||||
|
|
||||||
|
double exp_re_out[n_lines];
|
||||||
|
double exp_im_out[n_lines];
|
||||||
|
|
||||||
|
ofstream FILE;
|
||||||
|
|
||||||
|
ifstream INPUT(input_fn);
|
||||||
|
ifstream RESULTS(output_fn);
|
||||||
|
// Init test vector
|
||||||
|
for (unsigned i = 0; i < n_lines; i++) {
|
||||||
|
|
||||||
|
double a, b, c;
|
||||||
|
INPUT >> a >> b >> c;
|
||||||
|
values_re_in[i] = a;
|
||||||
|
values_im_in[i] = b;
|
||||||
|
angles_in[i] = c;
|
||||||
|
|
||||||
|
RESULTS >> a >> b;
|
||||||
|
exp_re_out[i] = a;
|
||||||
|
exp_im_out[i] = b;
|
||||||
|
}
|
||||||
|
INPUT.close();
|
||||||
|
RESULTS.close();
|
||||||
|
|
||||||
|
// Save the results to a file
|
||||||
|
FILE.open("results.dat");
|
||||||
|
|
||||||
|
// Executing the encoder
|
||||||
|
for (unsigned iter = 0; iter < n_lines; iter++) {
|
||||||
|
// Execute
|
||||||
|
|
||||||
|
cordic_t::process(angles_in[iter], values_re_in[iter], values_im_in[iter], values_re_out[iter], values_im_out[iter]);
|
||||||
|
|
||||||
|
// Display the results
|
||||||
|
// cout << "Series " << iter;
|
||||||
|
// cout << " Outcome: ";
|
||||||
|
|
||||||
|
FILE << values_re_out[iter].to_float() << ", " << values_re_out[iter].to_float() << endl;
|
||||||
|
|
||||||
|
REQUIRE_THAT(values_re_out[iter].to_float(), WithinAbsMatcher(exp_re_out[iter], 0.079997558593750));
|
||||||
|
REQUIRE_THAT(values_im_out[iter].to_float(), WithinAbsMatcher(exp_im_out[iter], 0.079997558593750));
|
||||||
|
}
|
||||||
|
FILE.close();
|
||||||
|
|
||||||
|
// Compare the results file with the golden results
|
||||||
|
// int retval = 0;
|
||||||
|
// Return 0 if the test passed
|
||||||
|
}
|
2
sources/tb/main_catch2.cpp
Normal file
2
sources/tb/main_catch2.cpp
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
|
||||||
|
#include <catch2/catch.hpp>
|
Loading…
Reference in a new issue