From 0d6f4fc08c9d71bc2d652ee345fa6e337b252425 Mon Sep 17 00:00:00 2001 From: anonymous Date: Wed, 15 Jun 2022 17:00:12 +0200 Subject: [PATCH] Add option to control interface and block level protocol - Fix converters when type is signed - Force interface type as pragma as TCL directives on template is nearly impossible. --- CMakeLists.txt | 52 ++++++++++++++++++ ...ript_type_strmlen_endian_from_bytes.tcl.in | 4 +- ...script_type_strmlen_endian_to_bytes.tcl.in | 4 +- sources/CConverter/CConverterFromBytes.hpp | 54 +++++++++++++++++-- sources/CConverter/CConverterToBytes.hpp | 54 +++++++++++++++++-- .../type_strmlen_endian_from_bytes.cpp.in | 7 ++- .../type_strmlen_endian_to_bytes.cpp.in | 7 ++- 7 files changed, 172 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f24c4b..1f16a04 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,12 +69,64 @@ option (PEDANTIC "use -Wall and -pedantic." ON) # Parameters # ################################################################################################## +set ( + PRM_ITF_BLK + "ap_ctrl_chain" + CACHE STRING "Block-level interface protocol." +) +set_property ( + CACHE PRM_ITF_BLK + PROPERTY STRINGS + "ap_ctrl_none" + "ap_ctrl_hs" + "ap_ctrl_chain" +) +set (ITF_BLK ${PRM_ITF_BLK}) + +set ( + PRM_ITF_IN + "axis" + CACHE STRING "Input stream interface protocol." +) +set_property ( + CACHE PRM_ITF_IN + PROPERTY STRINGS + "ap_hs" + "ap_fifo" + "axis" +) +set (ITF_IN ${PRM_ITF_IN}) + +set ( + PRM_ITF_OUT + "axis" + CACHE STRING "Output stream interface protocol." +) +set_property ( + CACHE PRM_ITF_OUT + PROPERTY STRINGS + "ap_hs" + "ap_fifo" + "axis" +) +set (ITF_OUT ${PRM_ITF_OUT}) + set ( PRM_TYPE "uint32_t" CACHE STRING "Type to convert to/from." ) set (TYPE ${PRM_TYPE}) +set ( + PRM_SIGNED + OFF + CACHE BOOL "If Type is signed or not." +) +if (PRM_SIGNED) + set (SIGNED "true") +else () + set (SIGNED "false") +endif () set ( PRM_STRMLEN diff --git a/hls_files/templates/script_type_strmlen_endian_from_bytes.tcl.in b/hls_files/templates/script_type_strmlen_endian_from_bytes.tcl.in index e73baef..44aee82 100644 --- a/hls_files/templates/script_type_strmlen_endian_from_bytes.tcl.in +++ b/hls_files/templates/script_type_strmlen_endian_from_bytes.tcl.in @@ -108,7 +108,9 @@ if { [ file exists "directives.tcl" ] } { source "directives.tcl" } -set_directive_interface -mode ap_ctrl_none ${TYPE}_${STRMLEN}_${ENDIAN}_from_bytes +# set_directive_interface -mode @ITF_BLK@ ${TYPE}_${STRMLEN}_${ENDIAN}_from_bytes +# set_directive_interface -mode @ITF_IN@ ${TYPE}_${STRMLEN}_${ENDIAN}_from_bytes strm_in +# set_directive_interface -mode @ITF_OUT@ ${TYPE}_${STRMLEN}_${ENDIAN}_from_bytes strm_out csim_design -clean -O -argv "${NLINES}" csynth_design diff --git a/hls_files/templates/script_type_strmlen_endian_to_bytes.tcl.in b/hls_files/templates/script_type_strmlen_endian_to_bytes.tcl.in index 87db1e3..5123228 100644 --- a/hls_files/templates/script_type_strmlen_endian_to_bytes.tcl.in +++ b/hls_files/templates/script_type_strmlen_endian_to_bytes.tcl.in @@ -108,7 +108,9 @@ if { [ file exists "directives.tcl" ] } { source "directives.tcl" } -set_directive_interface -mode ap_ctrl_none ${TYPE}_${STRMLEN}_${ENDIAN}_to_bytes +# set_directive_interface -mode @ITF_BLK@ ${TYPE}_${STRMLEN}_${ENDIAN}_to_bytes +# set_directive_interface -mode @ITF_IN@ ${TYPE}_${STRMLEN}_${ENDIAN}_from_bytes strm_in +# set_directive_interface -mode @ITF_OUT@ ${TYPE}_${STRMLEN}_${ENDIAN}_from_bytes strm_out csim_design -clean -O -argv "${NLINES}" csynth_design diff --git a/sources/CConverter/CConverterFromBytes.hpp b/sources/CConverter/CConverterFromBytes.hpp index 51b1aa5..e08ed44 100644 --- a/sources/CConverter/CConverterFromBytes.hpp +++ b/sources/CConverter/CConverterFromBytes.hpp @@ -41,11 +41,11 @@ #include #include -template +template class CConverterFromBytes; template -class CConverterFromBytes { +class CConverterFromBytes { public: template static void process(hls::stream & strm_in, hls::stream & strm_out) { @@ -69,7 +69,7 @@ public: }; template -class CConverterFromBytes { +class CConverterFromBytes { public: template static void process(hls::stream & strm_in, hls::stream & strm_out) { @@ -92,4 +92,52 @@ public: } }; +template +class CConverterFromBytes { +public: + template + static void process(hls::stream & strm_in, hls::stream & strm_out) { +#if !defined(XILINX_MAJOR) + static_assert(std::numeric_limits::is_integer, "T must be an integer C-type."); + static_assert(std::is_signed(), "T must be a signed type."); +#endif + LOOP_STR_B2T_LE: + for (uint32_t u = 0; u < stream_len; u++) { + ap_int word_buffer = 0; + LOOP_BYTE_B2T_LE: + for (uint32_t v = 0; v < sizeofT; v++) { + const ap_uint<8> byte_buffer = strm_in.read(); + + word_buffer >>= 8; + word_buffer(sizeofT * 8 - 1, (sizeofT - 1) * 8) = byte_buffer.range(); + } + strm_out.write(word_buffer); + } + } +}; + +template +class CConverterFromBytes { +public: + template + static void process(hls::stream & strm_in, hls::stream & strm_out) { +#if !defined(XILINX_MAJOR) + static_assert(std::numeric_limits::is_integer, "T must be an integer C-type."); + static_assert(std::is_signed(), "T must be an signed type."); +#endif + LOOP_STR_B2T_BE: + for (uint32_t u = 0; u < stream_len; u++) { + ap_int word_buffer = 0; + LOOP_BYTE_B2T_BE: + for (uint32_t v = 0; v < sizeofT; v++) { + const ap_uint<8> byte_buffer = strm_in.read(); + + word_buffer <<= 8; + word_buffer(7, 0) = byte_buffer.range(); + } + strm_out.write(word_buffer); + } + } +}; + #endif // _CONVERTER_FROM_BYTES_HPP_ diff --git a/sources/CConverter/CConverterToBytes.hpp b/sources/CConverter/CConverterToBytes.hpp index 19b5f76..edc3769 100644 --- a/sources/CConverter/CConverterToBytes.hpp +++ b/sources/CConverter/CConverterToBytes.hpp @@ -41,11 +41,11 @@ #include #include -template +template class CConverterToBytes; template -class CConverterToBytes { +class CConverterToBytes { public: template static void process(hls::stream & strm_in, hls::stream & strm_out) { @@ -68,7 +68,7 @@ public: }; template -class CConverterToBytes { +class CConverterToBytes { public: template static void process(hls::stream & strm_in, hls::stream & strm_out) { @@ -90,4 +90,52 @@ public: } }; +// SIGNED + +template +class CConverterToBytes { +public: + template + static void process(hls::stream & strm_in, hls::stream & strm_out) { +#if !defined(XILINX_MAJOR) + static_assert(std::numeric_limits::is_integer, "T must be an integer C-type."); + static_assert(std::is_signed(), "T must be an signed type."); +#endif + LOOP_STR_T2B_LE: + for (uint32_t u = 0; u < stream_len; u++) { + ap_int word_buffer = strm_in.read(); + LOOP_BYTE_T2B_LE: + for (uint32_t v = 0; v < sizeofT; v++) { + const ap_uint<8> byte_buffer = word_buffer(7, 0); + + strm_out.write(byte_buffer); + word_buffer >>= 8; + } + } + } +}; + +template +class CConverterToBytes { +public: + template + static void process(hls::stream & strm_in, hls::stream & strm_out) { +#if !defined(XILINX_MAJOR) + static_assert(std::numeric_limits::is_integer, "T must be an integer C-type."); + static_assert(std::is_signed(), "T must be an signed type."); +#endif + LOOP_STR_T2B_BE: + for (uint32_t u = 0; u < stream_len; u++) { + ap_int word_buffer = strm_in.read(); + LOOP_BYTE_T2B_BE: + for (uint32_t v = 0; v < sizeofT; v++) { + const ap_uint<8> byte_buffer = word_buffer(sizeofT * 8 - 1, (sizeofT - 1) * 8); + + strm_out.write(byte_buffer); + word_buffer <<= 8; + } + } + } +}; + #endif // _CONVERTER_TO_BYTES_HPP_ diff --git a/sources/top_converters/type_strmlen_endian_from_bytes.cpp.in b/sources/top_converters/type_strmlen_endian_from_bytes.cpp.in index 2d5859c..1d5548e 100644 --- a/sources/top_converters/type_strmlen_endian_from_bytes.cpp.in +++ b/sources/top_converters/type_strmlen_endian_from_bytes.cpp.in @@ -37,5 +37,10 @@ #include "top_converters/@TYPE@_@STRMLEN@_@ENDIAN@_from_bytes.hpp" void @TYPE@_@STRMLEN@_@ENDIAN@_from_bytes(hls::stream & strm_in, hls::stream<@TYPE@> & strm_out) { - CConverterFromBytes<@STRMLEN@, @ENDIAN@>::process(strm_in, strm_out); + // clang-foramt off +#pragma HLS interface @ITF_BLK@ port=return +#pragma HLS interface @ITF_IN@ port=strm_in +#pragma HLS interface @ITF_OUT@ port=strm_out + // clang-foramt on + CConverterFromBytes<@STRMLEN@, @ENDIAN@, @SIGNED@>::process(strm_in, strm_out); } diff --git a/sources/top_converters/type_strmlen_endian_to_bytes.cpp.in b/sources/top_converters/type_strmlen_endian_to_bytes.cpp.in index 7c636fe..7867e1e 100644 --- a/sources/top_converters/type_strmlen_endian_to_bytes.cpp.in +++ b/sources/top_converters/type_strmlen_endian_to_bytes.cpp.in @@ -37,5 +37,10 @@ #include "top_converters/@TYPE@_@STRMLEN@_@ENDIAN@_to_bytes.hpp" void @TYPE@_@STRMLEN@_@ENDIAN@_to_bytes(hls::stream<@TYPE@> & strm_in, hls::stream & strm_out) { - CConverterToBytes<@STRMLEN@, @ENDIAN@>::process(strm_in, strm_out); + // clang-foramt off +#pragma HLS interface @ITF_BLK@ port=return +#pragma HLS interface @ITF_IN@ port=strm_in +#pragma HLS interface @ITF_OUT@ port=strm_out + // clang-foramt on + CConverterToBytes<@STRMLEN@, @ENDIAN@, @SIGNED@>::process(strm_in, strm_out); }