From b72065e052ccaa3cd280f5760bf6e1833a90885e Mon Sep 17 00:00:00 2001 From: DrasLorus Date: Sun, 5 Jun 2022 17:05:36 +0200 Subject: [PATCH] Add experimental support for MSVC - Add an option `ENABLE_DEPFETCH` to use the CMake module FetchContent to pull dependencies from external locations. --- .gitignore | 4 +++ CMakeLists.txt | 53 ++++++++++++++++++++++++++----- sources/CCordicAbs/CCordicAbs.hpp | 14 ++++---- sources/tb/cordicabs_tb.cpp | 47 +++++++++++++++------------ 4 files changed, 83 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index 5d89477..3fe9829 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,7 @@ sources/tb/cordic_rom_tb_??*_*.?pp hls_files/cordicabs_16_4_6/* !hls_files/cordicabs_16_4_6/*.tcl + +.vs/ + +CMakeSettings.json diff --git a/CMakeLists.txt b/CMakeLists.txt index 147ddbd..864738d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,9 @@ if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSI set (IS_GNU_LEGACY ON) else () set (IS_GNU_LEGACY OFF) + if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_compile_options (/Zc:__cplusplus) + endif () endif () if (IS_GNU_LEGACY) @@ -73,6 +76,8 @@ option (ENABLE_SOFTWARE option (PEDANTIC "use -Wall and -pedantic." ON) option (ENABLE_GCOV "use GCOV and LCOV to assess code coverage." OFF) +option (ENABLE_DEPFETCH "Allow to fetch dependency from external sources." OFF) + # ################################################################################################## if (PEDANTIC) @@ -93,6 +98,10 @@ if (EXPORT_COMMANDS) set (CMAKE_EXPORT_COMPILE_COMMANDS ON) endif () +if (ENABLE_DEPFETCH) + include (FetchContent) +endif () + if (ENABLE_XILINX) set ( XILINX_HOME @@ -128,19 +137,33 @@ if (ENABLE_XILINX) endif () message (STATUS "AP headers must lie under ${AP_INCLUDE_DIR}") -else () - set ( +else () + if (ENABLE_DEPFETCH) + FetchContent_Declare ( + hlsaptypes + GIT_REPOSITORY https://github.com/DrasLorus/HLS_arbitrary_Precision_Types.git + ) + + FetchContent_MakeAvailable (hlsaptypes) + + find_file ( + AP_FIXED ap_fixed.h + HINTS ${hlsaptypes_SOURCE_DIR} + PATH_SUFFIXES "include" + ) + else () + set ( AP_TYPES_HINT /usr/include CACHE PATH "location of ap_types include directory." - ) + ) - find_file ( + find_file ( AP_FIXED ap_fixed.h HINTS ${AP_TYPES_HINT} - PATH_SUFFIXES ap_types hls_ap_types/include REQUIRED - ) - + PATH_SUFFIXES ap_types hls_ap_types/include + ) + endif () get_filename_component (AP_INCLUDE_DIR ${AP_FIXED} DIRECTORY) endif () @@ -175,8 +198,22 @@ if (ENABLE_TESTING) cmake_policy (SET CMP0110 NEW) endif () + + if (NOT IS_GNU_LEGACY) - find_package (Catch2 REQUIRED) + if (ENABLE_DEPFETCH) + FetchContent_Declare ( + Catch2 + GIT_REPOSITORY https://github.com/catchorg/Catch2.git + GIT_TAG v2.13.9 + ) + + FetchContent_MakeAvailable (Catch2) + list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/contrib) + else () + find_package (Catch2 REQUIRED) + endif () + add_library (catch_common_${PROJECT_NAME} OBJECT sources/tb/main_catch2.cpp) target_link_libraries (catch_common_${PROJECT_NAME} PUBLIC Catch2::Catch2) diff --git a/sources/CCordicAbs/CCordicAbs.hpp b/sources/CCordicAbs/CCordicAbs.hpp index c3bbf70..1c60152 100644 --- a/sources/CCordicAbs/CCordicAbs.hpp +++ b/sources/CCordicAbs/CCordicAbs.hpp @@ -122,14 +122,14 @@ public: const bool sign_B = B > 0; - const int64_t step_A = +B / int64_t(1U << (u - 1)); - const int64_t step_B = -A / int64_t(1U << (u - 1)); + const int64_t step_A = +B / int64_t(1LU << (u - 1)); + const int64_t step_B = -A / int64_t(1LU << (u - 1)); B = sign_B ? B + step_B : B - step_B; A = sign_B ? A + step_A : A - step_A; } - return A; + return uint64_t(A); } static constexpr uint64_t process(const std::complex & x_in) { @@ -144,21 +144,21 @@ public: const bool sign_B = B > 0; - const int64_t step_A = +B / int64_t(1U << (u - 1)); - const int64_t step_B = -A / int64_t(1U << (u - 1)); + const int64_t step_A = +B / int64_t(1LLU << (u - 1)); + const int64_t step_B = -A / int64_t(1LLU << (u - 1)); B = sign_B ? B + step_B : B - step_B; A = sign_B ? A + step_A : A - step_A; } - return A; + return uint64_t(A); } static constexpr double process(std::complex x_in) { const std::complex fx_x_in(int64_t(x_in.real() * double(in_scale_factor)), int64_t(x_in.imag() * double(in_scale_factor))); - const int64_t fx_out = process(fx_x_in); + const uint64_t fx_out = process(fx_x_in); return scale_cordic(double(fx_out)) / double(out_scale_factor); } diff --git a/sources/tb/cordicabs_tb.cpp b/sources/tb/cordicabs_tb.cpp index 0e5d406..530d14e 100644 --- a/sources/tb/cordicabs_tb.cpp +++ b/sources/tb/cordicabs_tb.cpp @@ -29,6 +29,13 @@ #include + +#ifdef _MSC_VER +#define R_FLAG "rt" +#else +#define R_FLAG "r" +#endif + using namespace std; using Catch::Matchers::Floating::WithinAbsMatcher; @@ -43,12 +50,12 @@ TEST_CASE("Constexpr CordicAbs works with C-Types", "[CORDICABS]") { constexpr unsigned n_lines = 100000; - complex values_in[n_lines]; - double values_out[n_lines]; + vector> values_in(n_lines); + vector values_out(n_lines); - double results[n_lines]; + vector results(n_lines); - FILE * INPUT = fopen(input_fn.c_str(), "r"); + FILE * INPUT = fopen(input_fn.c_str(), R_FLAG); // Init test vector for (unsigned i = 0; i < n_lines; i++) { @@ -94,12 +101,12 @@ TEST_CASE("Constexpr CordicAbs works with C-Types", "[CORDICABS]") { constexpr unsigned n_lines = 100000; - complex values_in[n_lines]; - int64_t values_out[n_lines]; + vector> values_in(n_lines); + vector values_out(n_lines); - double results[n_lines]; + vector results(n_lines); - FILE * INPUT = fopen(input_fn.c_str(), "r"); + FILE * INPUT = fopen(input_fn.c_str(), R_FLAG); // Init test vector for (unsigned i = 0; i < n_lines; i++) { @@ -149,13 +156,13 @@ TEST_CASE("Constexpr CordicAbs works with AP-Types", "[CORDICABS]") { constexpr unsigned n_lines = 100000; - ap_int re_values_in[n_lines]; - ap_int im_values_in[n_lines]; - ap_uint values_out[n_lines]; + vector> re_values_in(n_lines); + vector> im_values_in(n_lines); + vector> values_out(n_lines); - double results[n_lines]; + vector results(n_lines); - FILE * INPUT = fopen(input_fn.c_str(), "r"); + FILE * INPUT = fopen(input_fn.c_str(), R_FLAG); if (!bool(INPUT)) { throw(string("fopen failed for ") + input_fn + string(": ") + string(strerror(errno))); @@ -212,22 +219,22 @@ TEST_CASE("Constexpr CordicAbs are evaluated during compilation.", "[CORDICABS]" SECTION("W:16 - I:4 - Stages:6 - C-Types") { typedef CCordicAbs<16, 4, 6> cordic_abs; - constexpr const complex value_in[3] = {(1U << 12) * 97, -(1U << 12) * 33, (1U << 3) * 12}; + constexpr const complex value_in[3] = {int(1U << 12) * 97, -int(1U << 12) * 33, int(1U << 3) * 12}; - constexpr int64_t res10 = cordic_abs::process(value_in[0]); - constexpr int64_t res20 = cordic_abs::process(value_in[0]); + constexpr uint64_t res10 = cordic_abs::process(value_in[0]); + constexpr uint64_t res20 = cordic_abs::process(value_in[0]); static_assert(res10 == res20, "Test"); REQUIRE_FALSE(res10 == cordic_abs::process(complex(1, 0))); REQUIRE(res10 == cordic_abs::process(value_in[0])); - constexpr int64_t res11 = cordic_abs::process(value_in[1]); - constexpr int64_t res21 = cordic_abs::process(value_in[1]); + constexpr uint64_t res11 = cordic_abs::process(value_in[1]); + constexpr uint64_t res21 = cordic_abs::process(value_in[1]); static_assert(res11 == res21, "Test"); REQUIRE_FALSE(res11 == cordic_abs::process(complex(1, 0))); REQUIRE(res11 == cordic_abs::process(value_in[1])); - constexpr int64_t res12 = cordic_abs::process(value_in[2]); - constexpr int64_t res22 = cordic_abs::process(value_in[2]); + constexpr uint64_t res12 = cordic_abs::process(value_in[2]); + constexpr uint64_t res22 = cordic_abs::process(value_in[2]); static_assert(res12 == res22, "Test"); REQUIRE_FALSE(res12 == cordic_abs::process(complex(1, 0))); REQUIRE(res12 == cordic_abs::process(value_in[2]));