Add experimental support for MSVC

- Add an option `ENABLE_DEPFETCH` to use the CMake module FetchContent
  to pull dependencies from external locations.
This commit is contained in:
DrasLorus 2022-06-05 17:05:36 +02:00
parent d9f80fc165
commit b72065e052
4 changed files with 83 additions and 35 deletions

4
.gitignore vendored
View file

@ -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

View file

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

View file

@ -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<int64_t> & 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<double> x_in) {
const std::complex<int64_t> 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);
}

View file

@ -29,6 +29,13 @@
#include <catch2/catch.hpp>
#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<double> values_in[n_lines];
double values_out[n_lines];
vector<complex<double>> values_in(n_lines);
vector<double> values_out(n_lines);
double results[n_lines];
vector<double> 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<int64_t> values_in[n_lines];
int64_t values_out[n_lines];
vector<complex<int64_t>> values_in(n_lines);
vector<uint64_t> values_out(n_lines);
double results[n_lines];
vector<double> 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<cordic_abs::In_W> re_values_in[n_lines];
ap_int<cordic_abs::In_W> im_values_in[n_lines];
ap_uint<cordic_abs::Out_W> values_out[n_lines];
vector<ap_int<cordic_abs::In_W>> re_values_in(n_lines);
vector<ap_int<cordic_abs::In_W>> im_values_in(n_lines);
vector<ap_uint<cordic_abs::Out_W>> values_out(n_lines);
double results[n_lines];
vector<double> 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<int64_t> value_in[3] = {(1U << 12) * 97, -(1U << 12) * 33, (1U << 3) * 12};
constexpr const complex<int64_t> 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<int64_t>(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<int64_t>(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<int64_t>(1, 0)));
REQUIRE(res12 == cordic_abs::process(value_in[2]));