The code in Multi-Access Pointers on the Interface is written with intent that input
pointer d_i
and output pointer d_o
are implemented in RTL as FIFO (or handshake) interfaces to ensure that:
- Upstream producer modules supply new data each time a read is performed
on RTL port
d_i
. - Downstream consumer modules accept new data each time there is a write to
RTL port
d_o
.
When this code is compiled by standard C/C++ compilers, the multiple
accesses to each pointer is reduced to a single access. As far as the compiler is concerned,
there is no indication that the data on d_i
changes during
the execution of the function and only the final write to d_o
is relevant. The other writes are overwritten by the time the function
completes.
Vitis HLS matches the behavior of the
gcc
compiler and optimizes these reads and writes into a
single read operation and a single write operation. When the RTL is examined, there is only
a single read and write operation on each port.
The fundamental issue with this design is that the test bench and design do not adequately model how you expect the RTL ports to be implemented:
- You expect RTL ports that read and write multiple times during a transaction (and can stream the data in and out).
- The test bench supplies only a single input value and returns only a
single output value. A C/C++ simulation of Multi-Access Pointers on the Interface shows the following results, which
demonstrates that each input is being accumulated four times. The same value is being read
once and accumulated each time. It is not four separate
reads.
Din Dout 0 0 1 4 2 8 3 12
To make this design read and write to the RTL ports multiple times, use a
volatile
qualifier as shown in Multi-Access Pointers on the Interface. The volatile
qualifier tells the C/C++ compiler and Vitis HLS to make no assumptions about the pointer accesses, and to not optimize
them away. That is, the data is volatile and might change.
volatile
qualifier:- Prevents pointer access optimizations.
- Results in an RTL design that performs the expected four reads on
input port
d_i
and two writes to output portd_o
.
Even if the volatile
keyword is used, the
coding style of accessing a pointer multiple times still has an issue in that the function
and test bench do not adequately model multiple distinct reads and writes. In this case,
four reads are performed, but the same data is read four times. There are two separate
writes, each with the correct data, but the test bench captures data only for the final
write.
cosim_design -trace_level
to
create a trace file during RTL simulation and view the trace file in the appropriate
viewer.The Multi-Access volatile pointer interface can be implemented with wire interfaces. If a FIFO interface is specified, Vitis HLS creates an RTL test bench to stream new data on each read. Because no new data is available from the test bench, the RTL fails to verify. The test bench does not correctly model the reads and writes.