Array arguments are implemented by default as an ap_memory interface. This is a standard block RAM interface with data, address,
chip-enable, and write-enable ports.
An ap_memory interface can be implemented as a single-port of
dual-port interface. If Vitis HLS can determine that using
a dual-port interface will reduce the initial interval, it will automatically implement a
dual-port interface. The BIND_STORAGE pragma or directive is used to specify the memory
resource and if this directive is specified on the array with a single-port block RAM, a
single-port interface will be implemented. Conversely, if a dual-port interface is specified
using the BIND_STORAGE pragma and Vitis HLS determines
this interface provides no benefit it will automatically implement a single-port
interface.
If the array is accessed in a sequential manner an ap_fifo
interface can be used. As with the ap_hs interface, Vitis HLS will halt if it determines the data access is not sequential, report a
warning if it cannot determine if the access is sequential or issue no message if it
determines the access is sequential. The ap_fifo interface can only be used
for reading or writing, not both.
ap_memory, bram
The ap_memory and
bram interface port-level I/O protocols are used to implement array
arguments. This type of port-level I/O protocol can communicate with memory elements (for
example, RAMs and ROMs) when the implementation requires random accesses to the memory
address locations.
ap_fifo
interface instead. The ap_fifo interface reduces the hardware overhead,
because address generation is not performed.The ap_memory and
bram interface port-level I/O protocols are identical. The only
difference is the way Vivado IP integrator shows the
blocks:
- The
ap_memoryinterface appears as discrete ports. - The
braminterface appears as a single, grouped port. In IP integrator, you can use a single connection to create connections to all ports.
When using an ap_memory interface, specify the array targets using the BIND_STORAGE pragma. If
no target is specified for the arrays, Vitis HLS
determines whether to use a single or dual-port RAM interface.
The following figure shows an array named
d specified as a single-port block RAM. The port names are based on the
C/C++ function argument. For example, if the C/C++ argument is d, the
chip-enable is d_ce, and the input data is d_q0 based on
the output/q port of the BRAM.
After reset, the following occurs:
- After start is applied, the block begins normal operation.
- Reads are performed by applying
an address on the output address ports while asserting the output signal
d_ce.Note: For a default block RAM, the design expects the input datad_q0to be available in the next clock cycle. You can use the BIND_STORAGE pragma to indicate the RAM has a longer read latency. - Write operations are performed
by asserting output ports
d_ceandd_wewhile simultaneously applying the address and output datad_d0.
ap_fifo
When an output port is written to, its
associated output valid signal interface is the most
hardware-efficient approach when the design requires access to a memory element and the
access is always performed in a sequential manner, that is, no random access is required.
The ap_fifo port-level I/O protocol supports the following:
- Allows the port to be connected to a FIFO
- Enables complete, two-way
empty-fullcommunication - Works for arrays, pointers, and pass-by-reference argument types
ap_fifo interface often use pointers and might
access the same variable multiple times. To understand the importance of the volatile qualifier when using this coding style, see Multi-Access Pointers on the Interface.In the following example, in1 is a pointer that
accesses the current address, then two addresses
above the current address, and finally one address
below.
void foo(int* in1, ...) {
int data1, data2, data3;
...
data1= *in1;
data2= *(in1+2);
data3= *(in1-1);
...
}
If in1 is
specified as an ap_fifo interface, Vitis HLS checks the accesses, determines the accesses are not in sequential
order, issues an error, and halts. To read from non-sequential address locations, use an
ap_memory or bram interface.
You cannot specify an
ap_fifo interface on an argument that is both read from and written to.
You can only specify an ap_fifo interface on an input or an output
argument. A design with input argument in and output argument
out specified as ap_fifo interfaces behaves as shown in
the following figure.
For inputs, the following occurs:
- After ap_start is applied, the block begins normal operation.
- If the input port is ready to
be read but the FIFO is empty as indicated by input port
in_empty_nLow, the design stalls and waits for data to become available. - When the FIFO contains data as
indicated by input port
in_empty_nHigh, an output acknowledgein_readis asserted High to indicate the data was read in this cycle.
For outputs, the following occurs:
- After start is applied, the block begins normal operation.
- If an output port is ready to
be written to but the FIFO is full as indicated by
out_full_nLow, the data is placed on the output port but the design stalls and waits for the space to become available in the FIFO. - When space becomes available in
the FIFO as indicated by
out_full_nHigh, the output acknowledge signalout_writeis asserted to indicate the output data isvalid. - If the top-level function or
the top-level loop is pipelined using the
-rewindoption, Vitis HLS creates an additional output port with the suffix_lwr. When the last write to the FIFO interface completes, the_lwrport goes active-High.