-
Notifications
You must be signed in to change notification settings - Fork 48
Supported pragmas
WORK IN PROGRESS - This documentation is partial.
When the --generate-interface=INFER
option is set, the user is responsible for specifying the desired accelerator interfaces, usually on a per-argument basis. The information can be encoded in an XML file passed through the --interface-xml-filename
command-line option or inserted in the source code with pragmas.
Interface pragmas have the following syntax (case sensitive):
#pragma HLS_Interface <signal_name> <interface_type> [direct] [bundle=<bundle_name>]
-
signal_name
is the name of the variable that must be associated with the interface; -
interface_type
identifies what kind of interface will be generated; -
direct
must be added ifinterface_type
ism_axi
; -
bundle_name
can be used ifinterface_type
ism_axi
, to create one instance of the interface for every bundle name. Signals associated with the same bundle name will share the interface, while signals using different bundle names will use different interfaces. If no bundle is specified, all signals will share the same interface. The default bundle name isgmem
.
Available interface types are: none
, none_registered
, bus
, fifo
, handshake
, valid
, o_valid
, acknowledge
, array
, m_axi
, axis
. More detailed information on each interface type will be available on a different page of the Wiki.
#pragma HLS_interface var1 m_axi direct
#pragma HLS_interface var2 m_axi direct
short function (short * var1, unsigned short *var2)
{
/* Function code here */
}
This module needs to access two different addresses over an AXI bus. Addresses are passed as input to the function. For each function parameter, a pragma must be added immediately before the function definition, specifying that the interface type is m_axi. Since data for both parameters is available over the same bus, the bundle name can be omitted, and both will use the default bundle name. Bambu will treat the two function parameters var1 and var2 as AXI addresses; when generating a module for the function, a wrapper for the specified module will be generated as well and it will act as an AXI master node. Accesses to var1
and var2
will result in read/write requests from the wrapper to the bus.
#pragma HLS_interface var1 m_axi direct bundle=gmem0
#pragma HLS_interface var2 m_axi direct bundle=gmem1
short function (short * var1, unsigned short *var2)
{
/* Function code here */
}
In this case, the two parameters are addresses on two different AXI buses. Each parameter requires a pragma specifying the use of m_axi, bundle names must now be specified because there is a need for two separate interfaces. Bambu will generate two AXI interfaces, each handling the data of one of the two addresses.
When requesting an AXI interface, it is possible to add a customizable cache that can help reduce the average memory access latency by accessing data in the cache rather than performing the full transaction over the AXI bus.
Cache pragmas have the following syntax (case sensitive):
#pragma HLS_cache bundle=<bundle_name> way_size=<lines> line_size=<elements> [<cache_option> ...]
Cache options are separated by whitespaces, can be specified in any order, and are in the form <option_type> = <value>
. More detailed information on the caches generated by Bambu will be available on a different page of the Wiki.
Option | Default value | Description |
---|---|---|
bundle |
-- | Name of the AXI bundle that is going to use this cache, matching the one specified in one of the HLS_interface pragmas |
way_size |
-- | Number of lines in a way. If the value provided by the user is not a power of two, the number of lines will be the next power of two |
line_size |
-- | Number of elements in a cache line (not number of bytes). If the value provided by the user is not a power of two, the number of elements will be the next power of two |
n_ways |
1 | Number of ways in the cache. If the value provided by the user is not a power of two, the number of ways will be the next power of two |
bus_size |
size of the data type associated with the cache | Width of the RDATA and WDATA signals in the AXI bus. Available values are 32, 64, 128, 256, 512, and 1024 |
buffer_size |
2 | Size of the buffer storing pending write transactions. If the value provided by the user is not a power of two, the buffer size will be the next power of two |
rep_policy |
lru |
Type of replacement policy used by the cache, available values are lru (least recently used) and tree (tree-based pseudo-lru). This option has no effect if the number of ways is 1 |
write_policy |
wt |
Write policy used by the cache, available values are wt (write through no allocate) and wb (write back allocate) |
Bambu does not support associating multiple bundles to the same cache. Either the bundles must be merged, or multiple caches must be used.
Associating a single variable in a bundle to a cache is also not supprted. Either the variable must have its own bundle, or the cache must be associated with all the signals in the bundle.
#pragma HLS_interface var1 m_axi direct bundle=gmem0
#pragma HLS_interface var2 m_axi direct bundle=gmem1
#pragma HLS_cache bundle = gmem0 line_size = 64 way_size = 16
#pragma HLS_cache n_ways = 4 way_size = 32 bundle = gmem1 write_policy = wb
buffer_size = 2 rep_policy = tree bus_size = 64 line_size = 16
void function (int * var1, int * var2)
{
/* Function code here */
}
Two caches are generated, one associated with bundle gmem0
(and variable var1
), the other associated with bundle gmem1
(and variable var2
).
The first cache pragma specifies the mandatory options, leaving the rest to their default values: the generated cache will have a single way of 16 lines containing 64 ints each. The data bus will have the size of an int, and the write buffer will contain 2 pending write transactions. The write policy will be write through and the replacement policy will be irrelevant since there is only one way.
The second cache will have 4 ways, each containing 32 lines of 16 ints. The data bus will be 64 bits wide, and the write buffer will contain 2 pending write transactions. The write policy will be write back and the tree-based pseudo-lru replacement policy will be used to select cache lines that must be overwritten.
#pragma HLS_interface var1 m_axi direct bundle=gmem0
#pragma HLS_interface var2 m_axi direct bundle=gmem0
#pragma HLS_cache bundle = gmem0 line_size = 64 way_size = 16
void function (int * var1, int * var2)
{
/* Function code here */
}
Same bundle for both variables associated to one cache, resulting in memory accesses to both var1
and var2
that are intercepted by the same cache.
#pragma HLS_interface var1 m_axi direct bundle=gmem0
#pragma HLS_interface var2 m_axi direct bundle=gmem1
#pragma HLS_cache n_ways = 4 way_size = 32 bundle = gmem1 write_policy = wb
buffer_size = 2 rep_policy = tree bus_size = 64 line_size = 16
void function (int * var1, int * var2)
{
/* Function code here */
}
Accesses to var2
will be intercepted by a cache, accesses to var1
will result in direct requests on the AXI bus.