From 6afa99d7a1b474592590e9332d0b6190ea358329 Mon Sep 17 00:00:00 2001 From: anonymous Date: Fri, 13 May 2022 15:53:14 +0200 Subject: [PATCH] GNU 4.6 (consequently Xilinx 2019.1) is finally supported - if GNU version is less than 6.2: * Catch2 is disabled, a custom unit test is used instead, * Constexpr keyword is largely removed and less used (performance loss), * Only ML Cordic/Roms are compiled and tested. - Perfect compilation on g++ v4.6.4, should work on Vivado HLS (g++ v4.6.3). --- .gitignore | 3 +- CMakeLists.txt | 112 +++++++---- RomGenerators/CMakeLists.txt | 31 +-- .../RomGeneratorConst/RomGeneratorConst.hpp | 3 + .../sources/RomGeneratorML/RomGeneratorML.hpp | 35 +++- .../sources/RomRotateCommon/definitions.hpp | 2 +- RomGenerators/sources/main_legacy.cpp | 54 ++++-- .../CCordicRotateRom/CCordicRotateRom.hpp.in | 4 +- .../catch_less/cordic_rom_aptypes_tb.cpp.in | 179 ++++++++++++++++++ sources/tb/{ => catchy}/cordic_rom_tb.cpp.in | 0 sources/tb/{ => catchy}/cordic_tb.cpp | 1 - sources/tb/{ => catchy}/main_catch2.cpp | 0 12 files changed, 355 insertions(+), 69 deletions(-) create mode 100644 sources/tb/catch_less/cordic_rom_aptypes_tb.cpp.in rename sources/tb/{ => catchy}/cordic_rom_tb.cpp.in (100%) rename sources/tb/{ => catchy}/cordic_tb.cpp (99%) rename sources/tb/{ => catchy}/main_catch2.cpp (100%) diff --git a/.gitignore b/.gitignore index a2e344a..9db3a33 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ compile_commands.json RomGenerators/sources/main_generator_??*_*.cpp sources/CCordicRotateRom/CCordicRotateRom_*.?pp sources/CordicRoms/cordic_rom_*.?pp -sources/tb/cordic_rom_tb_??*_*.?pp \ No newline at end of file +sources/tb/catchy/cordic_rom_tb_??*_*.?pp +sources/tb/catch_less/cordic_rom_aptypes_tb_??*_*.?pp \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 27af801..5fef1a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,10 +15,20 @@ # If not, see . # -cmake_minimum_required (VERSION 3.16.0 FATAL_ERROR) +cmake_minimum_required (VERSION 3.18.0 FATAL_ERROR) # setting this is required -set (CMAKE_CXX_STANDARD 14) +project ( + CordicRotate + LANGUAGES CXX + VERSION 0.1 +) + +if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.2)) + set (CMAKE_CXX_STANDARD 11) +else () + set (CMAKE_CXX_STANDARD 14) +endif () set (CMAKE_CXX_STANDARD_REQUIRED ON) set (CMAKE_CXX_EXTENSIONS OFF) set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../lib) @@ -27,20 +37,13 @@ set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../bin) set (CMAKE_EXPORT_COMPILE_COMMANDS true) -project ( - CordicRotate - LANGUAGES CXX - VERSION 0.1 -) - # ################################################################################################## # Options # ################################################################################################## option (EXPORT_COMMANDS "export compile commands, for use with clangd for example." ON) option (ENABLE_XILINX "use Xilinx provided proprietary headers." OFF) - -option (ENABLE_TESTING "use Catch2 in conjunction with CTest as a test suite." ON) +option (ENABLE_TESTING "use Catch2 (if possible) in conjunction with CTest as a test suite." ON) option (ENABLE_SOFTWARE "use C++ standard library types (like std::complex). Unsuitable for synthesis." ON ) @@ -65,7 +68,7 @@ if (ENABLE_XILINX) ) set ( XILINX_VER - "2020.2" + "2019.1" CACHE STRING "Xilinx software version to use." ) @@ -169,10 +172,15 @@ target_link_libraries (cordic_rom_gen PUBLIC romgen) file (GLOB ALL_CORDIC_ROM_SOURCES sources/CCordicRotateRom/*.cpp) list (REMOVE_ITEM ALL_CORDIC_ROM_SOURCES sources/CCordicRotateRom/${CORDIC_ROM_SOURCE}) -add_library ( - cordic STATIC sources/CCordicRotateSmart/CCordicRotateSmart.cpp - sources/CCordicRotateConstexpr/CCordicRotateConstexpr.cpp ${ALL_CORDIC_ROM_SOURCES} +add_library (cordic STATIC ${ALL_CORDIC_ROM_SOURCES}) +if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.2 + ) ) + target_sources ( + cordic PRIVATE sources/CCordicRotateSmart/CCordicRotateSmart.cpp + sources/CCordicRotateConstexpr/CCordicRotateConstexpr.cpp + ) +endif () target_include_directories (cordic PUBLIC sources) target_include_directories (cordic SYSTEM PUBLIC ${AP_INCLUDE_DIR}) target_link_libraries (cordic PUBLIC romgen cordic_rom_gen) @@ -180,27 +188,63 @@ target_link_libraries (cordic PUBLIC romgen cordic_rom_gen) # ################################################################################################## if (ENABLE_TESTING) - find_package (Catch2 REQUIRED) - - string ( - CONFIGURE - ${CMAKE_CURRENT_SOURCE_DIR}/sources/tb/cordic_rom_tb_${ROM_TYPE}_${CORDIC_W}_${CORDIC_STAGES}_${CORDIC_Q}_${CORDIC_DIVIDER}.cpp - TB_SOURCE - ) - configure_file (sources/tb/cordic_rom_tb.cpp.in ${TB_SOURCE} @ONLY) - - add_library (catch_common_${PROJECT_NAME} OBJECT sources/tb/main_catch2.cpp) - target_link_libraries (catch_common_${PROJECT_NAME} PUBLIC Catch2::Catch2) - - file (GLOB ALL_ROM_TB_SOURCES sources/tb/cordic_rom_*.cpp) - list (REMOVE_ITEM ALL_ROM_TB_SOURCES ${TB_SOURCE}) - - add_executable (cordic_tb sources/tb/cordic_tb.cpp ${TB_SOURCE} ${ALL_ROM_TB_SOURCES}) - target_link_libraries (cordic_tb PRIVATE cordic catch_common_${PROJECT_NAME}) - include (CTest) - include (Catch) - catch_discover_tests (cordic_tb WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data) + if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.2)) + string ( + CONFIGURE + ${CMAKE_CURRENT_SOURCE_DIR}/sources/tb/catch_less/cordic_rom_aptypes_tb_${ROM_TYPE}_${CORDIC_W}_${CORDIC_STAGES}_${CORDIC_Q}_${CORDIC_DIVIDER}.cpp + TB_SOURCE + ) + configure_file (sources/tb/catch_less/cordic_rom_aptypes_tb.cpp.in ${TB_SOURCE} @ONLY) + + file (GLOB ALL_ROM_TB_SOURCES sources/tb/catch_less/cordic_rom_aptypes*.cpp) + list (REMOVE_ITEM ALL_ROM_TB_SOURCES ${TB_SOURCE}) + + get_filename_component (FILE_RADIX ${TB_SOURCE} NAME_WE) + add_executable (${FILE_RADIX} ${TB_SOURCE}) + target_link_libraries (${FILE_RADIX} PRIVATE cordic) + + add_test ( + NAME ${FILE_RADIX} + COMMAND ${FILE_RADIX} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data + ) + + foreach (TB_FILE ${ALL_ROM_TB_SOURCES}) + get_filename_component (FILE_RADIX ${TB_FILE} NAME_WE) + add_executable (${FILE_RADIX} ${TB_FILE}) + target_link_libraries (${FILE_RADIX} PRIVATE cordic) + + add_test ( + NAME ${FILE_RADIX} + COMMAND ${FILE_RADIX} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data + ) + endforeach () + + else () + find_package (Catch2 REQUIRED) + + string ( + CONFIGURE + ${CMAKE_CURRENT_SOURCE_DIR}/sources/tb/catchy/cordic_rom_tb_${ROM_TYPE}_${CORDIC_W}_${CORDIC_STAGES}_${CORDIC_Q}_${CORDIC_DIVIDER}.cpp + TB_SOURCE + ) + + configure_file (sources/tb/catchy/cordic_rom_tb.cpp.in ${TB_SOURCE} @ONLY) + + add_library (catch_common_${PROJECT_NAME} OBJECT sources/tb/catchy/main_catch2.cpp) + target_link_libraries (catch_common_${PROJECT_NAME} PUBLIC Catch2::Catch2) + + file (GLOB ALL_ROM_TB_SOURCES sources/tb/catchy/cordic_rom_*.cpp) + list (REMOVE_ITEM ALL_ROM_TB_SOURCES ${TB_SOURCE}) + + add_executable (cordic_tb sources/tb/catchy/cordic_tb.cpp ${TB_SOURCE} ${ALL_ROM_TB_SOURCES}) + target_link_libraries (cordic_tb PRIVATE cordic catch_common_${PROJECT_NAME}) + + include (Catch) + catch_discover_tests (cordic_tb WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data) + endif () endif () file (GLOB ALL_ROM_HEADERS sources/CordicRoms/cordic_rom_*.hpp) diff --git a/RomGenerators/CMakeLists.txt b/RomGenerators/CMakeLists.txt index 10c5ff6..da3f23e 100644 --- a/RomGenerators/CMakeLists.txt +++ b/RomGenerators/CMakeLists.txt @@ -15,10 +15,20 @@ # If not, see . # -cmake_minimum_required (VERSION 3.16.0 FATAL_ERROR) -# setting this is required +cmake_minimum_required (VERSION 3.18.0 FATAL_ERROR) +# setting this is -set (CMAKE_CXX_STANDARD 14) +project ( + CordicRomGenerator + LANGUAGES CXX + VERSION 0.1 +) + +if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.2)) + set (CMAKE_CXX_STANDARD 11) +else () + set (CMAKE_CXX_STANDARD 14) +endif () set (CMAKE_CXX_STANDARD_REQUIRED ON) set (CMAKE_CXX_EXTENSIONS OFF) set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../lib) @@ -27,15 +37,14 @@ set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../bin) set (CMAKE_EXPORT_COMPILE_COMMANDS true) -project ( - CordicRomGenerator - LANGUAGES CXX - VERSION 0.1 -) +set (IS_GNU (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")) +set (IS_GNU_LEGACY ${IS_GNU} AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.2)) + +add_library (romgen sources/RomGeneratorML/RomGeneratorML.cpp) +if (NOT IS_GNU_LEGACY) + target_sources (romgen PUBLIC sources/RomGeneratorConst/RomGeneratorConst.cpp) +endif () -add_library ( - romgen sources/RomGeneratorML/RomGeneratorML.cpp sources/RomGeneratorConst/RomGeneratorConst.cpp -) target_include_directories (romgen PUBLIC sources) if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") diff --git a/RomGenerators/sources/RomGeneratorConst/RomGeneratorConst.hpp b/RomGenerators/sources/RomGeneratorConst/RomGeneratorConst.hpp index 7d5ff45..8bf8ec8 100644 --- a/RomGenerators/sources/RomGeneratorConst/RomGeneratorConst.hpp +++ b/RomGenerators/sources/RomGeneratorConst/RomGeneratorConst.hpp @@ -20,6 +20,8 @@ #ifndef _ROM_GENERATOR_CONST_ #define _ROM_GENERATOR_CONST_ +#if __cplusplus >= 201402L || XILINX_MAJOR > 2019 + #include #include #include @@ -180,4 +182,5 @@ void generate_rom_header_cst_raw(const char * filename = "rom_cordic.txt") { fprintf(rom_file, "%03d\n\n", uint16_t(rom.rom[rom.max_length - 1])); } +#endif // STANDARD GUARD #endif // _ROM_GENERATOR_CONST_ \ No newline at end of file diff --git a/RomGenerators/sources/RomGeneratorML/RomGeneratorML.hpp b/RomGenerators/sources/RomGeneratorML/RomGeneratorML.hpp index be9fb80..75138d9 100644 --- a/RomGenerators/sources/RomGeneratorML/RomGeneratorML.hpp +++ b/RomGenerators/sources/RomGeneratorML/RomGeneratorML.hpp @@ -29,6 +29,12 @@ namespace rcr = rom_cordic_rotate; +#if __cplusplus >= 201402L || XILINX_MAJOR > 2019 +#define OWN_CONSTEXPR constexpr +#else +#define OWN_CONSTEXPR +#endif + template class CRomGeneratorML { static_assert(In_W > 0, "Inputs can't be on zero bits."); @@ -38,16 +44,23 @@ class CRomGeneratorML { static_assert(rcr::is_pow_2(), "divider must be a power of 2."); public: +#if __cplusplus >= 201402L || XILINX_MAJOR > 2019 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 = rcr::needed_bits(); static constexpr int64_t scale_factor = int64_t(1U << (In_W - 1)); - +#else + const double rotation; + const double q; + const unsigned max_length; + const unsigned addr_length; + const int64_t scale_factor; +#endif private: - constexpr std::complex cordic_ML(const std::complex & x_in, - uint8_t counter) { + OWN_CONSTEXPR std::complex cordic_ML(const std::complex & x_in, + uint8_t counter) { int64_t A = x_in.real(); int64_t B = x_in.imag(); @@ -73,9 +86,21 @@ private: } public: +#if __cplusplus >= 201402L || XILINX_MAJOR > 2019 uint8_t rom[max_length]; +#else + uint8_t rom[2 * Tq * divider]; +#endif - CRomGeneratorML() { + CRomGeneratorML() +#if __cplusplus < 201402L + : rotation(rcr::pi / divider), + q(Tq), + max_length(2 * Tq * divider), + addr_length(rcr::needed_bits<2 * Tq * divider - 1>()), + scale_factor(int64_t(1U << (In_W - 1))) +#endif + { for (unsigned n = 0; n < max_length; n++) { const double re_x = floor(double(scale_factor - 1) * cos(-rotation / double(q) * double(n))); const double im_x = floor(double(scale_factor - 1) * sin(-rotation / double(q) * double(n))); @@ -158,4 +183,6 @@ void generate_rom_header_ml_raw(const char * filename) { fprintf(rom_file, "%03d\n\n", uint16_t(rom.rom[rom.max_length - 1])); } +#undef OWN_CONSTEXPR + #endif // _ROM_GENERATOR_ML \ No newline at end of file diff --git a/RomGenerators/sources/RomRotateCommon/definitions.hpp b/RomGenerators/sources/RomRotateCommon/definitions.hpp index 1575ca8..b638faf 100644 --- a/RomGenerators/sources/RomRotateCommon/definitions.hpp +++ b/RomGenerators/sources/RomRotateCommon/definitions.hpp @@ -36,7 +36,7 @@ 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) +#if __cplusplus >= 201402L || XILINX_MAJOR > 2019 constexpr uint32_t needed_bits(uint32_t value) { uint32_t result = 0; diff --git a/RomGenerators/sources/main_legacy.cpp b/RomGenerators/sources/main_legacy.cpp index 608cd3b..e3080d0 100644 --- a/RomGenerators/sources/main_legacy.cpp +++ b/RomGenerators/sources/main_legacy.cpp @@ -26,10 +26,17 @@ using namespace std; +#if __cplusplus >= 201402L || XILINX_MAJOR > 2019 +#define OWN_CONSTEXPR constexpr +#else +#define OWN_CONSTEXPR +#endif + template -constexpr complex cordic(complex x_in, - uint8_t counter, - const uint8_t * rom_cordic) { +OWN_CONSTEXPR complex cordic( + complex x_in, + uint8_t counter, + const uint8_t * rom_cordic) { int64_t A = x_in.real(); int64_t B = x_in.imag(); @@ -54,18 +61,7 @@ constexpr complex cordic(complex x_in, return {A, B}; } -template -void checkMC() { - const CRomGeneratorML<16, NStages, 64> rom; - - string fn = "result_MC_W16_S" + to_string(NStages) + "_Q64.dat"; - ofstream res_file(fn); - - for (unsigned u = 0; u < rom.max_length; u++) { - auto res = cordic(4096, u, rom.rom); - res_file << double(res.real() * 155) / 1048576. << ", " << double(res.imag() * 155) / 1048576. << endl; - } -} +#if __cplusplus >= 201402L || XILINX_MAJOR > 2019 template void checkConst() { @@ -80,6 +76,34 @@ void checkConst() { } } +#else + +template +void generate_rom_header_cst_raw(const string &) {} + +template +void generate_rom_header_cst(const string &) {} + +template +void checkConst() {} + +#endif + + +template +void checkMC() { + const CRomGeneratorML<16, NStages, 64, 2> rom; + + string fn = "result_MC_W16_S" + to_string(NStages) + "_Q64.dat"; + ofstream res_file(fn); + + for (unsigned u = 0; u < rom.max_length; u++) { + complex res = cordic(4096, u, rom.rom); + res_file << double(res.real() * 155) / 1048576. << ", " << double(res.imag() * 155) / 1048576. << endl; + } +} + + int main(int argc, char * argv[]) { uint8_t stages; diff --git a/sources/CCordicRotateRom/CCordicRotateRom.hpp.in b/sources/CCordicRotateRom/CCordicRotateRom.hpp.in index b6af7c2..dbc087c 100644 --- a/sources/CCordicRotateRom/CCordicRotateRom.hpp.in +++ b/sources/CCordicRotateRom/CCordicRotateRom.hpp.in @@ -73,7 +73,7 @@ public: return in * kn_i / 16U; } -#if !defined(__SYNTHESIS__) && defined(SOFTWARE) +#if !defined(__SYNTHESIS__) && defined(SOFTWARE) && __cplusplus >= 201402L static constexpr std::complex cordic(std::complex x_in, uint8_t counter) { @@ -124,7 +124,7 @@ public: const ap_uint<8> & counter, ap_int & re_out, ap_int & im_out) { - const ap_uint R = cordic_roms::@ROM_TYPE@_@CORDIC_W@_@CORDIC_STAGES@_@CORDIC_Q@_@CORDIC_DIVIDER@[counter]; + const ap_uint R = *(cordic_roms::@ROM_TYPE@_@CORDIC_W@_@CORDIC_STAGES@_@CORDIC_Q@_@CORDIC_DIVIDER@ + counter); ap_int A = bool(R[0]) ? ap_int(-re_in) : re_in; ap_int B = bool(R[0]) ? ap_int(-im_in) : im_in; diff --git a/sources/tb/catch_less/cordic_rom_aptypes_tb.cpp.in b/sources/tb/catch_less/cordic_rom_aptypes_tb.cpp.in new file mode 100644 index 0000000..9bf4da4 --- /dev/null +++ b/sources/tb/catch_less/cordic_rom_aptypes_tb.cpp.in @@ -0,0 +1,179 @@ +/* + * + * Copyright 2022 Camille "DrasLorus" Monière. + * + * This file is part of CORDIC_Rotate_APFX. + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU + * Lesser General Public License as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with this program. + * If not, see . + * + */ + +#include "CCordicRotateRom/CCordicRotateRom_@ROM_TYPE@_@CORDIC_W@_@CORDIC_STAGES@_@CORDIC_Q@_@CORDIC_DIVIDER@.hpp" +#include +#include + +using namespace std; + +typedef CCordicRotateRom<4, @ROM_TYPE@, @CORDIC_W@, @CORDIC_STAGES@, @CORDIC_Q@, @CORDIC_DIVIDER@> cordic_rom; + +template +int section_1() { + // SECTION("W:@CORDIC_W@ - I:4 - Stages:@CORDIC_STAGES@ - q:@CORDIC_Q@ - div:@CORDIC_DIVIDER@") {} + + int counted_errors = 0; + + static constexpr cordic_rom cordic {}; + + string input_fn = "../data/input.dat"; + + constexpr double rotation = cordic_rom::rotation; + constexpr double q = cordic_rom::q; + constexpr uint64_t cnt_mask = 0xFF; // Value dependant of the way the ROM is initialized + + constexpr unsigned Out_W = cordic_rom::Out_W; + constexpr unsigned In_W = cordic_rom::In_W; + + ap_int values_re_in[n_lines]; + ap_int values_im_in[n_lines]; + ap_int values_re_out[n_lines]; + ap_int values_im_out[n_lines]; + + double results_re[n_lines]; + double results_im[n_lines]; + + FILE * INPUT = fopen(input_fn.c_str(), "r"); + + // Init test vector + for (unsigned i = 0; i < n_lines; i++) { + double a, b, r; + fscanf(INPUT, "%lf,%lf,%lf\n", &a, &b, &r); + + const complex c {a, b}; + values_re_in[i] = int64_t(a * double(cordic_rom::in_scale_factor)); + values_im_in[i] = int64_t(b * double(cordic_rom::in_scale_factor)); + + const complex e = c * exp(complex(0., rotation / q * (i & cnt_mask))); + results_re[i] = e.real(); + results_im[i] = e.imag(); + } + + fclose(INPUT); + + constexpr double abs_margin = double(1 << cordic.Out_I) * 2. / 100.; + + // Executing the CORDIC + for (unsigned iter = 0; iter < n_lines; iter++) { + // Execute + const uint8_t counter = uint8_t(iter & cnt_mask); + + cordic_rom::cordic( + values_re_in[iter], values_im_in[iter], + counter, + values_re_out[iter], values_im_out[iter]); + + const double res_re = values_re_out[iter].to_double() * 5. / 8. / cordic_rom::out_scale_factor; + const double res_im = values_im_out[iter].to_double() * 5. / 8. / cordic_rom::out_scale_factor; + if (abs(res_re - results_re[iter]) > abs_margin) { + counted_errors++; + } + if (abs(res_im - results_im[iter]) > abs_margin) { + counted_errors++; + } + } + + return counted_errors; +} + +template +int section_2() { + // SECTION("W:@CORDIC_W@ - I:4 - Stages:@CORDIC_STAGES@ - q:@CORDIC_Q@ - div:@CORDIC_DIVIDER@ - internal scaling") + int counted_errors = 0; + + static constexpr cordic_rom cordic {}; + + string input_fn = "../data/input.dat"; + + constexpr double rotation = cordic_rom::rotation; + constexpr double q = cordic_rom::q; + constexpr uint64_t cnt_mask = 0xFF; // Value dependant of the way the ROM is initialized + + constexpr unsigned Out_W = cordic_rom::Out_W; + constexpr unsigned In_W = cordic_rom::In_W; + + ap_int values_re_in[n_lines]; + ap_int values_im_in[n_lines]; + ap_int values_re_out[n_lines]; + ap_int values_im_out[n_lines]; + + double results_re[n_lines]; + double results_im[n_lines]; + + FILE * INPUT = fopen(input_fn.c_str(), "r"); + + // Init test vector + for (unsigned i = 0; i < n_lines; i++) { + double a, b, r; + fscanf(INPUT, "%lf,%lf,%lf\n", &a, &b, &r); + + const complex c {a, b}; + values_re_in[i] = int64_t(a * double(cordic_rom::in_scale_factor)); + values_im_in[i] = int64_t(b * double(cordic_rom::in_scale_factor)); + + const complex e = c * exp(complex(0., rotation / q * (i & cnt_mask))); + results_re[i] = e.real(); + results_im[i] = e.imag(); + } + + fclose(INPUT); + + constexpr double abs_margin = double(1 << cordic.Out_I) * 2. / 100.; + + // Executing the CORDIC + for (unsigned iter = 0; iter < n_lines; iter++) { + // Execute + const uint8_t counter = uint8_t(iter & cnt_mask); + + cordic_rom::cordic( + values_re_in[iter], values_im_in[iter], + counter, + values_re_out[iter], values_im_out[iter]); + + const double res_re = cordic_rom::scale_cordic(values_re_out[iter]).to_double() / cordic_rom::out_scale_factor; + const double res_im = cordic_rom::scale_cordic(values_im_out[iter]).to_double() / cordic_rom::out_scale_factor; + + if (abs(res_re - results_re[iter]) > abs_margin) { + counted_errors++; + } + if (abs(res_im - results_im[iter]) > abs_margin) { + counted_errors++; + } + } + + return counted_errors; +} + +int main(int, char **) { + + int counted_errors = 0; + + const string test_case = "ROM-based Cordic (TPL @ROM_TYPE@, @CORDIC_W@, @CORDIC_STAGES@, @CORDIC_Q@, @CORDIC_DIVIDER@) works with AP-Types"; + constexpr unsigned n_lines = 100000; + + cout << "Test case: " << test_case << endl; + + counted_errors += section_1(); + counted_errors += section_2(); + + cout << (counted_errors == 0 ? "SUCCESS" : "FAILURE") << "." << endl; + + return counted_errors; +} diff --git a/sources/tb/cordic_rom_tb.cpp.in b/sources/tb/catchy/cordic_rom_tb.cpp.in similarity index 100% rename from sources/tb/cordic_rom_tb.cpp.in rename to sources/tb/catchy/cordic_rom_tb.cpp.in diff --git a/sources/tb/cordic_tb.cpp b/sources/tb/catchy/cordic_tb.cpp similarity index 99% rename from sources/tb/cordic_tb.cpp rename to sources/tb/catchy/cordic_tb.cpp index 58f1926..656ab90 100644 --- a/sources/tb/cordic_tb.cpp +++ b/sources/tb/catchy/cordic_tb.cpp @@ -63,7 +63,6 @@ TEST_CASE("Adaptive CORDIC work as intended", "[!mayfail][!hide][WIP]") { fclose(INPUT); fclose(RESULTS); - constexpr double abs_margin = double(1 << 6) * 3. / 100.; // Save the results to a file diff --git a/sources/tb/main_catch2.cpp b/sources/tb/catchy/main_catch2.cpp similarity index 100% rename from sources/tb/main_catch2.cpp rename to sources/tb/catchy/main_catch2.cpp