TAPA Library (libtapa)
Task Library
-
struct task
Defines a parent task instantiating children task instances.
Canonical usage:
tapa::task() .invoke(...) .invoke(...) ... ;
A parent task itself does not do any computation. By default, a parent task will not finish until all its children task instances finish. Such children task instances are joined to their parent. The alternative is to detach a child from the parent. If a child task instance is instantiated and detached, the parent will no longer wait for the child task to finish. Detached tasks are very useful when infinite loops can be used.
Subclassed by tapa::hls_compat::task
Public Functions
-
explicit task()
Constructs a
tapa::task
.
-
template<typename Func, typename ...Args>
inline task &invoke(Func &&func, Args&&... args) Invokes a task and instantiates a child task instance.
- Parameters:
func – Task function definition of the instantiated child.
args – Arguments passed to
func
.
- Returns:
Reference to the caller
tapa::task
.
-
template<int mode, typename Func, typename ...Args>
inline task &invoke(Func &&func, Args&&... args) Invokes a task and instantiates a child task instance with the given instatiation mode.
- Template Parameters:
mode – Instatiation mode (
join
ordetach
).- Parameters:
func – Task function definition of the instantiated child.
args – Arguments passed to
func
.
- Returns:
Reference to the caller
tapa::task
.
-
template<int mode, int n, typename Func, typename ...Args>
inline task &invoke(Func &&func, Args&&... args) Invokes a task
n
times and instantiatesn
child task instances with the given instatiation mode.- Template Parameters:
mode – Instatiation mode (
join
ordetach
).n – Instatiation count.
- Parameters:
func – Task function definition of the instantiated child.
args – Arguments passed to
func
.
- Returns:
Reference to the caller
tapa::task
.
-
explicit task()
-
struct seq
Class that generates a sequence of integers as task arguments.
Canonical usage:
void TaskFoo(int i, ...) { ... } tapa::task() .invoke<3>(TaskFoo, tapa::seq(), ...) ... ;
TaskFoo
will be invoked three times, receiving0
,1
, and2
as the first argument, respectively.
Stream Library
A blocking operation blocks if the stream is not available (empty or full) until the stream becomes available.
A non-blocking operation always returns immediately.
A destructive operation changes the state of the stream.
A non-destructive operation does not change the state of the stream.
-
template<typename T>
class istream : public virtual tapa::internal::basic_stream<T> Provides consumer-side operations to a
tapa::stream
where it is used as an input.This class should only be used in task function parameters and should never be instatiated directly.
Subclassed by tapa::internal::unbound_stream< T >
Public Functions
-
inline bool empty() const
Tests whether the stream is empty.
This is a non-blocking and non-destructive operation.
- Returns:
Whether the stream is empty.
-
inline bool try_eot(bool &is_eot) const
Tests whether the next token is EoT.
This is a non-blocking and non-destructive operation.
- Parameters:
is_eot – [out] Uninitialized if the stream is empty. Otherwise, updated to indicate whether the next token is EoT.
- Returns:
Whether
is_eot
is updated.
-
inline bool eot(bool &is_success) const
Tests whether the next token is EoT.
This is a non-blocking and non-destructive operation.
- Parameters:
is_success – [out] Whether the next token is available.
- Returns:
Whether the next token is available and is EoT.
-
inline bool eot(std::nullptr_t) const
Tests whether the next token is EoT.
This is a non-blocking and non-destructive operation.
- Returns:
Whether the next token is available and is EoT.
-
inline bool try_peek(T &value) const
Peeks the stream.
This is a non-blocking and non-destructive operation.
The next token must not be EoT.
- Parameters:
value – [out] Uninitialized if the stream is empty. Otherwise, updated to be the value of the next token.
- Returns:
Whether
value
is updated.
-
inline T peek(bool &is_success) const
Peeks the stream.
This is a non-blocking and non-destructive operation.
The next token must not be EoT.
- Parameters:
is_success – [out] Whether the next token is available.
- Returns:
The value of the next token is returned if it is available. Otherwise, default-constructed
T()
is returned.
-
inline T peek(std::nullptr_t) const
Peeks the stream.
This is a non-blocking and non-destructive operation.
The next token must not be EoT.
- Returns:
The value of the next token is returned if it is available. Otherwise, default-constructed
T()
is returned.
-
inline T peek(bool &is_success, bool &is_eot) const
Peeks the stream.
This is a non-blocking and non-destructive operation.
- Parameters:
is_success – [out] Whether the next token is available.
is_eot – [out] Set to
false
if the stream is empty. Otherwise, updated to indicate whether the next token is EoT.
- Returns:
The value of the next token is returned if it is available. Otherwise, default-constructed
T()
is returned.
-
inline bool try_read(T &value)
Reads the stream.
This is a non-blocking and destructive operation.
The next token must not be EoT.
- Parameters:
value – [out] Uninitialized if the stream is empty. Otherwise, updated to be the value of the next token.
- Returns:
Whether
value
is updated.
-
inline T read()
Reads the stream.
This is a blocking and destructive operation.
The next token must not be EoT.
- Returns:
The value of the next token.
-
inline istream &operator>>(T &value)
Reads the stream.
This is a blocking and destructive operation.
The next token must not be EoT.
- Parameters:
value – [out] The value of the next token.
- Returns:
*this
.
-
inline T read(bool &is_success)
Reads the stream.
This is a non-blocking and destructive operation.
The next token must not be EoT.
- Parameters:
is_success – [out] Whether the next token is available.
- Returns:
The value of the next token is returned if it is available. Otherwise, default-constructed
T()
is returned.
-
inline T read(std::nullptr_t)
Reads the stream.
This is a non-blocking and destructive operation.
The next token must not be EoT.
- Returns:
The value of the next token is returned if it is available. Otherwise, default-constructed
T()
is returned.
-
inline T read(const T &default_value, bool *is_success = nullptr)
Reads the stream.
This is a non-blocking and destructive operation.
- Parameters:
default_value – [in] Value to return if the stream is empty.
is_success – [out] Updated to indicate whether the next token is available if
is_success
is notnullptr
.
- Returns:
The value of the next token is returned if it is available. Otherwise,
default_value
is returned.
-
inline bool try_open()
Consumes an EoT token.
This is a non-blocking and destructive operation.
The next token must be EoT.
- Returns:
Whether an EoT token is consumed.
-
inline void open()
Consumes an EoT token.
This is a blocking and destructive operation.
The next token must be EoT.
-
inline bool empty() const
-
template<typename T, uint64_t S>
class istreams : public virtual tapa::internal::basic_streams<T> Provides consumer-side operations to an array of
tapa::stream
where they are used as inputs.This class should only be used in task function parameters and should never be instatiated directly.
Subclassed by tapa::internal::unbound_streams< T, S >
Public Functions
-
inline istream<T> operator[](int pos) const
References a
tapa::stream
in the array.- Parameters:
pos – Position of the array reference.
- Returns:
tapa::istream
referenced in the array.
Public Static Attributes
-
static constexpr int length = S
Length of the
tapa::stream
array.
-
inline istream<T> operator[](int pos) const
-
template<typename T>
class ostream : public virtual tapa::internal::basic_stream<T> Provides producer-side operations to a
tapa::stream
where it is used as an output.This class should only be used in task function parameters and should never be instatiated directly.
Subclassed by tapa::internal::unbound_stream< T >
Public Functions
-
inline bool full() const
Tests whether the stream is full.
This is a non-blocking and non-destructive operation.
- Returns:
Whether the stream is full.
-
inline bool try_write(const T &value)
Writes
value
to the stream.This is a non-blocking and destructive operation.
- Parameters:
value – [in] The value to write.
- Returns:
Whether
value
has been written successfully.
-
inline void write(const T &value)
Writes
value
to the stream.This is a blocking and destructive operation.
- Parameters:
value – [in] The value to write.
-
inline ostream &operator<<(const T &value)
Writes
value
to the stream.This is a blocking and destructive operation.
- Parameters:
value – [in] The value to write.
- Returns:
*this
.
-
inline bool try_close()
Produces an EoT token to the stream.
This is a non-blocking and destructive operation.
- Returns:
Whether the EoT token has been written successfully.
-
inline void close()
Produces an EoT token to the stream.
This is a blocking and destructive operation.
-
inline bool full() const
-
template<typename T, uint64_t S>
class ostreams : public virtual tapa::internal::basic_streams<T> Provides producer-side operations to an array of
tapa::stream
where they are used as outputs.This class should only be used in task function parameters and should never be instatiated directly.
Subclassed by tapa::internal::unbound_streams< T, S >
Public Functions
-
inline ostream<T> operator[](int pos) const
References a
tapa::stream
in the array.- Parameters:
pos – Position of the array reference.
- Returns:
tapa::ostream
referenced in the array.
Public Static Attributes
-
static constexpr int length = S
Length of the
tapa::stream
array.
-
inline ostream<T> operator[](int pos) const
-
template<typename T, uint64_t N = kStreamDefaultDepth>
class stream : public tapa::internal::unbound_stream<T> Defines a communication channel between two task instances.
Public Functions
-
inline stream()
Constructs a
tapa::stream
.
-
template<size_t S>
inline stream(const char (&name)[S]) Constructs a
tapa::stream
with the given name for debugging.- Parameters:
name – [in] Name of the communication channel (for debugging only).
-
inline stream()
-
template<typename T, uint64_t S, uint64_t N = kStreamDefaultDepth>
class streams : public tapa::internal::unbound_streams<T, S> Defines an array of
tapa::stream
.Public Functions
-
inline streams()
Constructs a
tapa::streams
array.
-
template<size_t name_length>
inline streams(const char (&name)[name_length]) Constructs a
tapa::streams
array with the given base name for debugging.The actual name of each
tapa::stream
would bename[i]
.- Parameters:
name – [in] Base name of the streams (for debugging only).
-
inline stream<T, N> operator[](int pos) const
References a
tapa::stream
in the array.- Parameters:
pos – Position of the array reference.
- Returns:
tapa::stream
referenced in the array.
Public Static Attributes
-
static constexpr int length = S
Count of
tapa::stream
in the array.
-
static constexpr int depth = N
Depth of each
tapa::stream
in the array.
-
inline streams()
MMAP Library
-
template<typename T>
class async_mmap : public tapa::mmap<T> Defines a view of a piece of consecutive memory with asynchronous random accesses.
Public Types
-
using addr_t = int64_t
Type of the addresses.
-
using resp_t = uint8_t
Type of the write responses.
Public Members
-
ostream<addr_t> read_addr
Provides access to the read address channel.
Each value written to this channel triggers an asynchronous memory read request. Consecutive requests may be coalesced into a long burst request.
-
istream<T> read_data
Provides access to the read data channel.
Each value read from this channel represents the data retrieved from the underlying memory system.
-
ostream<addr_t> write_addr
Provides access to the write address channel.
Each value written to this channel triggers an asynchronous memory write request. Consecutive requests may be coalesced into a long burst request.
-
using addr_t = int64_t
-
template<typename T>
class mmap Defines a view of a piece of consecutive memory with synchronous random accesses.
Subclassed by tapa::async_mmap< T >, tapa::hmap< T, chan_count, chan_size >
Public Functions
-
inline explicit mmap(T *ptr)
Constructs a
tapa::mmap
with unknown size.- Parameters:
ptr – Pointer to the start of the mapped memory.
-
inline mmap(T *ptr, uint64_t size)
Constructs a
tapa::mmap
with the givensize
.- Parameters:
ptr – Pointer to the start of the mapped memory.
size – Size of the mapped memory (in unit of element count).
-
template<typename Container>
inline explicit mmap(Container &container) Constructs a
tapa::mmap
from the givencontainer
.- Parameters:
container – Container holding a
tapa::mmap
. Must implementdata()
andsize()
.
-
inline operator T*()
Implicitly casts to a regular pointer.
tapa::mmap
should be used just like a pointer in the kernel.
-
inline mmap &operator++()
Increments the start of the mapped memory.
- Returns:
The incremented
tapa::mmap
.
-
inline mmap &operator--()
Decrements the start of the mapped memory.
- Returns:
The decremented
tapa::mmap
.
-
inline mmap operator++(int)
Increments the start of the mapped memory.
- Returns:
The
tapa::mmap
before incrementation.
-
inline mmap operator--(int)
Decrements the start of the mapped memory.
- Returns:
The
tapa::mmap
before decrementation.
-
inline T *data() const
Retrieves the start of the mapped memory.
This should be used on the host only.
- Returns:
The start of the mapped memory.
-
inline T *get() const
Retrieves the start of the mapped memory.
This should be used on the host only.
- Returns:
The start of the mapped memory.
-
inline uint64_t size() const
Retrieves the size of the mapped memory.
This should be used on the host only.
- Returns:
The size of the mapped memory (in unit of element count).
-
template<uint64_t N>
inline mmap<vec_t<T, N>> vectorized() const Reinterprets the element type of the mapped memory as
tapa::vec_t<T, N>
.This should be used on the host only. The size of mapped memory must be a multiple of
N
.- Template Parameters:
N – Vector length of the new element type.
- Returns:
tapa::mmap
of the same piece of memory but of typetapa::vec_t<T, N>
.
-
template<typename U>
inline mmap<U> reinterpret() const Reinterprets the element type of the mapped memory as
U
.This should be used on the host only. Both
T
andU
must have standard layout. The host memory pointer must be properly aligned. Ifsizeof(U)
>sizeof(T)
, the size of mapped memory must be a multiple ofsizeof(U)/sizeof
(T) (which must be an integer itself). Ifsizeof(U)
<sizeof(T)
,sizeof(T)
must be a multiple ofsizeof(U)
.- Template Parameters:
U – The new element type.
- Returns:
tapa::mmap<U>
of the same piece of memory.
-
inline explicit mmap(T *ptr)
-
template<typename T, uint64_t S>
class mmaps Defines an array of
tapa::mmap
.Public Functions
-
template<typename PtrContainer, typename SizeContainer>
inline mmaps(const PtrContainer &pointers, const SizeContainer &sizes) Constructs a
tapa::mmap
array from the givenpointers
andsizes
.- Parameters:
ptrs – Pointers to the start of the array of mapped memory.
sizes – Sizes of each mapped memory (in unit of element count).
-
template<typename Container>
inline explicit mmaps(Container &container) Constructs a
tapa::mmap
array from the givencontainer
.- Parameters:
container – Container holding an array of
tapa::mmap
.container
must implementoperator
[] that returns a container suitable for constructing atapa::mmap
.
-
inline mmap<T> &operator[](int idx)
References a
tapa::mmap
in the array.
-
template<uint64_t N>
inline mmaps<vec_t<T, N>, S> vectorized() const Reinterprets the element type of each mapped memory as
tapa::vec_t<T, N>
.This should be used on the host only. The size of each mapped memory must be a multiple of
N
.- Template Parameters:
N – Vector length of the new element type.
- Returns:
tapa::mmap
of the same pieces of memory but of typetapa::vec_t<T, N>
.
-
template<typename U>
inline mmaps<U, S> reinterpret() const Reinterprets the element type of each mapped memory as
U
.This should be used on the host only. Both
T
andU
must have standard layout. The host memory pointers must be properly aligned. Ifsizeof(U)
>sizeof(T)
, the size of each mapped memory must be a multiple ofsizeof(U)/sizeof
(T) (which must be an integer itself). Ifsizeof(U)
<sizeof(T)
,sizeof(T)
must be a multiple ofsizeof(N)
.- Template Parameters:
U – The new element type.
- Returns:
tapa::mmaps<U, S>
of the same pieces of memory.
-
template<typename PtrContainer, typename SizeContainer>
Utility Library
-
template<typename T>
inline constexpr int tapa::widthof() Queries width (in bits) of the type.
- Template Parameters:
T – Type to be queried.
- Returns:
T::width
if it exists,sizeof(T) * CHAR_BIT
otherwise.
-
template<typename T>
inline constexpr int tapa::widthof(T object) Queries width (in bits) of the object.
Note
Unlike
sizeof
, the argument expression is evaluated (though unused).- Template Parameters:
T – Type of
object
.- Parameters:
object – Object to be queried.
- Returns:
T::width
if it exists,sizeof(T) * CHAR_BIT
otherwise.
HLS-Compat Library
The HLS-compat library provides a set of APIs compatible with Vitis HLS stream behavior to ease migration from Vitis HLS.
Warning
tapa::hls_compat
APIs are software simulation only and are NOT
synthesizable.
Before synthesis, remove #include <tapa/host/compat.h>
and replace any
tapa::hls_compat
API with their synthesizable equivalent.
-
template<typename T>
using tapa::hls_compat::stream = ::tapa::stream<T, ::tapa::internal::kInfiniteDepth> An infinite-depth stream that has the same behavior as
hls::stream
.Intended for defining streams without knowing their depth for synthesis:
... #include <tapa.h> #include <tapa/host/compat.h> ... void Top() { tapa::hls_compat::stream<int> data_q("data"); ... tapa::task() .invoke(...) .invoke(...) ... ; }
Software simulation only; NOT synthesizable. Replace with
tapa::stream
for synthesis.
-
template<typename T>
using tapa::hls_compat::stream_interface = ::tapa::internal::unbound_stream<T> I/O direction agnostic interface that accepts both
tapa::stream
andtapa::hls_compat::stream
.Intended for declaring parameters without knowing the I/O direction:
... #include <tapa.h> #include <tapa/host/compat.h> ... void Compute(tapa::hls_compat::stream_interface<int>& data_in_q) { int data = data_in_q.read(); ... }
Software simulation only; NOT synthesizable. Replace with
tapa::istream
/tapa::ostream
for synthesis.
-
struct task : public tapa::task
Same as
tapa::task
, except that tasks are scheduled sequentially.Intended for debugging code migrated from HLS:
... #include <tapa.h> #include <tapa/host/compat.h> ... void Top() { ... tapa::hls_compat::task() .invoke(...) .invoke(...) ... ; }
Software simulation only; NOT synthesizable. Replace with
tapa::task
for synthesis.
TAPA Compiler (tapa)
tapa
The TAPA compiler.
tapa [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...
Options
- -v, --verbose
Increase logging verbosity.
- -q, --quiet
Decrease logging verbosity.
- -w, --work-dir <DIR>
Specify working directory.
- --recursion-limit <limit>
Override Python recursion limit.
analyze
Analyze TAPA program and store the program description.
tapa analyze [OPTIONS]
Options
- -f, --input <input_files>
Required Input file, usually TAPA C++ source code.
- -t, --top <TASK>
Required Name of the top-level task.
- -c, --cflags <cflags>
Compiler flags for the kernel, may appear many times.
- --flatten-hierarchy, --keep-hierarchy
–keep-hierarchy (default) will generate RTL with the same hierarchy as the TAPA C++ source code; –flatten-hierarchy will flatten the hierarchy with all leaf-level tasks instantiated in the top module
- --no-vitis-mode, --vitis-mode
–vitis-mode (default) will generate .xo files for Vitis v++ command, with AXI4-Lite interfaces for task arguments and return values, and AXI4-Stream interfaces for task FIFOs; –no-vitis-mode will only generate RTL code with Vitis HLS compatible interfaces
compile
Compile a TAPA program to a hardware design.
tapa compile [OPTIONS]
Options
- -f, --input <input_files>
Required Input file, usually TAPA C++ source code.
- -t, --top <TASK>
Required Name of the top-level task.
- -c, --cflags <cflags>
Compiler flags for the kernel, may appear many times.
- --flatten-hierarchy, --keep-hierarchy
–keep-hierarchy (default) will generate RTL with the same hierarchy as the TAPA C++ source code; –flatten-hierarchy will flatten the hierarchy with all leaf-level tasks instantiated in the top module
- --no-vitis-mode, --vitis-mode
–vitis-mode (default) will generate .xo files for Vitis v++ command, with AXI4-Lite interfaces for task arguments and return values, and AXI4-Stream interfaces for task FIFOs; –no-vitis-mode will only generate RTL code with Vitis HLS compatible interfaces
- --part-num <part_num>
Target FPGA part number. Must be specified if –platform is not provided.
- -p, --platform <platform>
Target Vitis platform. Must be specified if –part-num is not provided.
- --clock-period <clock_period>
Target clock period in nanoseconds.
- --skip-hls-based-on-mtime, --no-skip-hls-based-on-mtime
Skip HLS if an output tarball exists and is newer than the source C++ file. This can lead to incorrect results; use at your own risk.
- --other-hls-configs <other_hls_configs>
Additional compile options for Vitis HLS, e.g., –other-hls-configs “config_compile -unsafe_math_optimizations”
- --print-fifo-ops, --no-print-fifo-ops
Print all FIFO operations in cosim.
- --print-fifo-ops, --no-print-fifo-ops
Print all FIFO operations in cosim.
- -o, --output <output>
Output packed .xo Xilinx object file.
- -s, --bitstream-script <bitstream_script>
Script file to generate the bitstream.
g++
Invoke g++ with TAPA include and library paths.
This is intended only for usage with pre-built binary installation. Developers building TAPA from source should compile binaries using bazel.
tapa g++ [OPTIONS] [ARGV]...
Options
- --executable <executable>
Run the specified executable instead of g++.
Arguments
- ARGV
Optional argument(s)
link
Link the generated RTL.
tapa link [OPTIONS]
Options
- --print-fifo-ops, --no-print-fifo-ops
Print all FIFO operations in cosim.
pack
Pack the generated RTL into a Xilinx object file.
tapa pack [OPTIONS]
Options
- -o, --output <output>
Output packed .xo Xilinx object file.
- -s, --bitstream-script <bitstream_script>
Script file to generate the bitstream.
synth
Synthesize the TAPA program into RTL code.
tapa synth [OPTIONS]
Options
- --part-num <part_num>
Target FPGA part number. Must be specified if –platform is not provided.
- -p, --platform <platform>
Target Vitis platform. Must be specified if –part-num is not provided.
- --clock-period <clock_period>
Target clock period in nanoseconds.
- --skip-hls-based-on-mtime, --no-skip-hls-based-on-mtime
Skip HLS if an output tarball exists and is newer than the source C++ file. This can lead to incorrect results; use at your own risk.
- --other-hls-configs <other_hls_configs>
Additional compile options for Vitis HLS, e.g., –other-hls-configs “config_compile -unsafe_math_optimizations”
- --print-fifo-ops, --no-print-fifo-ops
Print all FIFO operations in cosim.
version
Print TAPA version to standard output.
tapa version [OPTIONS]