Skip to content

Commit d9b6c5e

Browse files
committed
Merge branch 'master' of github.com:definelicht/hlslib
2 parents 7414a62 + 56e2ebf commit d9b6c5e

File tree

7 files changed

+101
-30
lines changed

7 files changed

+101
-30
lines changed

cmake/FindVitis.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,9 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
187187
if(NOT DEFINED XRT_ROOT)
188188

189189
find_path(XRT_SEARCH_PATH libxilinxopencl.so
190-
PATHS /opt/xilinx/xrt /opt/Xilinx/xrt
190+
PATHS ENV XILINX_XRT
191+
/opt/xilinx/xrt /opt/Xilinx/xrt
191192
/tools/Xilinx/xrt /tools/xilinx/xrt
192-
ENV XILINX_XRT
193193
PATH_SUFFIXES lib)
194194
get_filename_component(XRT_ROOT ${XRT_SEARCH_PATH} DIRECTORY)
195195
mark_as_advanced(XRT_SEARCH_PATH)

include/hlslib/xilinx/Simulation.h

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
/// @author Johannes de Fine Licht (definelicht@inf.ethz.ch)
2-
/// @copyright This software is copyrighted under the BSD 3-Clause License.
2+
/// @copyright This software is copyrighted under the BSD 3-Clause License.
33

44
#pragma once
55

66
#ifndef HLSLIB_SYNTHESIS
7+
#include <condition_variable>
8+
#include <mutex>
9+
#include <queue>
710
#include <thread>
811
#include <vector>
912
// #include "hlslib/Stream.h"
@@ -16,9 +19,10 @@
1619
// which will launch them as a C++ thread when running simulation, but will
1720
// fall back on normal function calls when running synthesis.
1821
//
22+
// The macro HLSLIB_DATAFLOW_INIT must be called before adding dataflow
23+
// functions, in order to initialize the local context.
1924
// The macro HLSLIB_DATAFLOW_FINALIZE must be called before returning from the
2025
// top level function to join the dataflow threads.
21-
// HLSLIB_DATAFLOW_INIT currently has no purpose, but is included for symmetry.
2226
//
2327
// TODO: HLSLIB_DATAFLOW_FUNCTION does not work when calling templated functions
2428
// with multiple arguments, as it considers the comma a separator between
@@ -36,11 +40,11 @@ namespace hlslib {
3640
#else
3741
namespace {
3842
class _Dataflow {
39-
40-
private:
43+
public:
4144
inline _Dataflow() {}
4245
inline ~_Dataflow() { this->Join(); }
4346

47+
private:
4448
template <typename T>
4549
struct non_deducible {
4650
using type = T;
@@ -60,39 +64,27 @@ class _Dataflow {
6064
}
6165

6266
public:
63-
inline static _Dataflow& Get() { // Singleton pattern
64-
static _Dataflow df;
65-
return df;
66-
}
67-
6867
template <class Ret, typename... Args>
6968
void AddFunction(Ret (*func)(Args...), non_deducible_t<Args>... args) {
7069
threads_.emplace_back(func, passed_by(std::forward<Args>(args),
7170
std::is_reference<Args>{})...);
7271
}
7372

74-
// template <typename T, typename... Args>
75-
// Stream<T>& EmplaceStream(Args&&... args) {
76-
// streams_.emplace_back(std::unique_ptr<Stream<T>>(new Stream<T>(args...)));
77-
// return *static_cast<Stream<T> *>(streams_.back().get());
78-
// }
79-
8073
inline void Join() {
81-
for (auto &t : threads_) {
74+
for (auto& t : threads_) {
8275
t.join();
8376
}
8477
threads_.clear();
8578
}
8679

87-
private:
80+
private:
8881
std::vector<std::thread> threads_{};
89-
// std::vector<std::unique_ptr<_StreamBase>> streams_{};
9082
};
91-
#define HLSLIB_DATAFLOW_INIT()
83+
#define HLSLIB_DATAFLOW_INIT() ::hlslib::_Dataflow __hlslib_dataflow_context;
9284
#define HLSLIB_DATAFLOW_FUNCTION(func, ...) \
93-
::hlslib::_Dataflow::Get().AddFunction(func, __VA_ARGS__)
94-
#define HLSLIB_DATAFLOW_FINALIZE() ::hlslib::_Dataflow::Get().Join();
95-
}
85+
__hlslib_dataflow_context.AddFunction(func, __VA_ARGS__)
86+
#define HLSLIB_DATAFLOW_FINALIZE() __hlslib_dataflow_context.Join();
87+
} // namespace
9688
#endif
9789

98-
} // End namespace hlslib
90+
} // End namespace hlslib

xilinx_test/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ if(Threads_FOUND)
4646
add_executable(TestShiftRegister test/TestShiftRegister.cpp)
4747
target_link_libraries(TestShiftRegister ${CMAKE_THREAD_LIBS_INIT} catch)
4848
add_test(TestShiftRegister TestShiftRegister)
49+
add_executable(TestSubflow test/TestSubflow.cpp kernels/Subflow.cpp)
50+
target_link_libraries(TestSubflow ${CMAKE_THREAD_LIBS_INIT} catch)
51+
add_test(TestSubflow TestSubflow)
4952
else()
5053
message(WARNING "Threads not found. Disabling multi-PE kernel tests.")
5154
endif()
@@ -128,3 +131,4 @@ sdaccel_target("AccumulateInt" "-DHLSLIB_COMPILE_ACCUMULATE_INT")
128131
synthesis_target("ShiftRegister" "")
129132
sdaccel_target("ShiftRegister" "")
130133
synthesis_target("StreamAPI" "")
134+
synthesis_target("Subflow" "")

xilinx_test/include/Subflow.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#pragma once
2+
3+
using Data_t = int;
4+
constexpr int kSize = 128;
5+
6+
extern "C" void Subflow(const Data_t* memIn, Data_t* memOut);

xilinx_test/kernels/AccumulateInt.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ void AccumulateInt(DataPack_t const *memoryIn, DataPack_t *memoryOut, int size,
2222
// functions with multiple template arguments
2323
#ifndef HLSLIB_SYNTHESIS
2424
HLSLIB_DATAFLOW_INIT();
25-
hlslib::_Dataflow::Get().AddFunction(Read<DataPack_t>, memoryIn, pipeIn,
26-
iterations * size);
27-
hlslib::_Dataflow::Get().AddFunction(
25+
__hlslib_dataflow_context.AddFunction(Read<DataPack_t>, memoryIn, pipeIn,
26+
iterations * size);
27+
__hlslib_dataflow_context.AddFunction(
2828
hlslib::AccumulateSimple<DataPack_t, Operator>, pipeIn, pipeOut,
2929
iterations, size);
30-
hlslib::_Dataflow::Get().AddFunction(Write<DataPack_t>, pipeOut,
31-
memoryOut, iterations);
30+
__hlslib_dataflow_context.AddFunction(Write<DataPack_t>, pipeOut, memoryOut,
31+
iterations);
3232
HLSLIB_DATAFLOW_FINALIZE();
3333
#else
3434
Read<DataPack_t>(memoryIn, pipeIn, iterations * size);

xilinx_test/kernels/Subflow.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include "Subflow.h"
2+
3+
#include "hlslib/xilinx/Simulation.h"
4+
#include "hlslib/xilinx/Stream.h"
5+
6+
void ReadIn(const Data_t* memIn, hlslib::Stream<Data_t>& inPipe) {
7+
for (unsigned i = 0; i < kSize; ++i) {
8+
#pragma HLS PIPELINE II=1
9+
inPipe.Push(memIn[i]);
10+
}
11+
}
12+
13+
void AddOne(hlslib::Stream<Data_t>& inPipe, hlslib::Stream<Data_t>& internal) {
14+
for (unsigned i = 0; i < kSize; ++i) {
15+
#pragma HLS PIPELINE II=1
16+
internal.Push(inPipe.Pop() + 1);
17+
}
18+
}
19+
20+
void MultiplyByTwo(hlslib::Stream<Data_t>& internal,
21+
hlslib::Stream<Data_t>& outPipe) {
22+
for (unsigned i = 0; i < kSize; ++i) {
23+
#pragma HLS PIPELINE II=1
24+
outPipe.Push(internal.Pop() * 2);
25+
}
26+
}
27+
28+
void Subtask(hlslib::Stream<Data_t>& inPipe, hlslib::Stream<Data_t>& outPipe) {
29+
HLSLIB_DATAFLOW_INIT();
30+
hlslib::Stream<Data_t> internal;
31+
HLSLIB_DATAFLOW_FUNCTION(AddOne, inPipe, internal);
32+
HLSLIB_DATAFLOW_FUNCTION(MultiplyByTwo, internal, outPipe);
33+
HLSLIB_DATAFLOW_FINALIZE();
34+
}
35+
36+
void WriteOut(hlslib::Stream<Data_t>& outPipe, Data_t* memOut) {
37+
for (unsigned i = 0; i < kSize; ++i) {
38+
#pragma HLS PIPELINE II=1
39+
memOut[i] = outPipe.Pop();
40+
}
41+
}
42+
43+
void Subflow(const Data_t* memIn, Data_t* memOut) {
44+
#pragma HLS DATAFLOW
45+
HLSLIB_DATAFLOW_INIT();
46+
hlslib::Stream<Data_t> inPipe, outPipe;
47+
HLSLIB_DATAFLOW_FUNCTION(ReadIn, memIn, inPipe);
48+
HLSLIB_DATAFLOW_FUNCTION(Subtask, inPipe, outPipe);
49+
HLSLIB_DATAFLOW_FUNCTION(WriteOut, outPipe, memOut);
50+
HLSLIB_DATAFLOW_FINALIZE();
51+
}

xilinx_test/test/TestSubflow.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <random>
2+
3+
#include "Subflow.h"
4+
#include "catch.hpp"
5+
6+
TEST_CASE("Subflow", "[Subflow]") {
7+
std::random_device rd;
8+
std::default_random_engine re(rd());
9+
std::uniform_int_distribution<Data_t> dist(10, 1);
10+
std::vector<Data_t> memIn(kSize), memOut(kSize);
11+
for (unsigned i = 0; i < kSize; ++i) {
12+
memIn[i] = dist(re);
13+
}
14+
Subflow(memIn.data(), memOut.data());
15+
for (unsigned i = 0; i < kSize; ++i) {
16+
REQUIRE(memOut[i] == (memIn[i] + 1) * 2);
17+
}
18+
}

0 commit comments

Comments
 (0)