首先简介一下HLS的整套开发流程。详细流程可参考[1][2]。
1、设计C/C++代码以及C/C++的TestBench
2、C Simulation,验证软件代码是否正确
3、C Synthesis,将C/C++化为Verilog/VHDL
4、C/RTL Co-Simulation,将C的TestBench与生成的RTL一起进行Simulation
5、Export RTL,导出IP核
HLS的使用本身不是一个难点,我猜Vivado HLS本身就是一个Eclipse搭起来的IDE,所以只要对Eclipse上手就行。难点在于代码移植。
LZ77的软件算法在实现的时候,是用std::vector实现的。std::vector用了动态内存分配,是HLS综合不了的。所以数组必须要用固定长度的数组。而对于FPGA来说,片上SRAM又是有限的,不可能把文件的所有数据都存进来。又恰好因为LZ77本身就是一个流式算法。因此我决定在FPGA上开一个缓冲区,PS与PL的数据交换采用流(hls::stream[3],接口是axi_stream),实现了一个FIFO_Array类在硬件实现上来替代std::vector[6]。
但后来在Vivado里IP Integrator里Validate Design的时候发现了问题。Vivado一直提醒Stream没有TLast信号[4][10]。这个是一个非常大的坑。对于AXI_Stream,TLast信号为高标志着一批数据发送的结束。应当携带在本批数据的最后一个数据上向外发送。当使用纯C数据类型初始化hls::stream template时,HLS的Compiler是不会综合出TLast信号的。没有TLast信号,就会导致PL端IP与DMA、以及PS的数据传输出现严重的问题。PS端一直空等DMA,因为没有TLast信号,DMA无从得知数据是否传输完毕。
所以,我们必须要使用ap_axis<8,0,0,0>数据类型来传输字节[5]。这样综合的时候就会综合出TLast信号,因此我把FIFO_Array做了改动,使其适应ap_axis数据类型,变成了FIFO_Array_APInt类[7]。除此之外,在对应的Hardware C Code里面需要有对应的发送tlast信号的语句:发送普通数据tlast信号为0[8];发送EOF时tlast信号为1[9]。
AXI_Stream是个不好搞的东西,流式传输数据必须要用到DMA,它和axi-lite总线不大相同。axi-lite总线只要简单的Run Block/Connection Automation就可以在Vivado IP Integrator里面配置好了连线。而AXI_Stream需要手动添加、设置DMA IP核与AXI Stream Data FIFO IP核才可以。下一篇文章详细讲解一下。
参考资料:
[1]: https://github.com/xupgit/High-Level-Synthesis-Flow-on-Zynq-using-Vivado-HLS/blob/master/slides/11_HLS_Intro.pdf
[2]: https://github.com/xupgit/High-Level-Synthesis-Flow-on-Zynq-using-Vivado-HLS/blob/master/slides/12_Using_VivadoHLS.pdf
[3]: Using HLS Streams, UG902, Page 214: https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_3/ug902-vivado-high-level-synthesis.pdf
[4]: AXI4-Stream Signal Summary, UG1037, Page 167: https://www.xilinx.com/support/documentation/ip_documentation/axi_ref_guide/latest/ug1037-vivado-axi-reference-guide.pdf
[5]: AXI4-Stream Interfaces with Side-Channels, UG902, Page 98: https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_3/ug902-vivado-high-level-synthesis.pdf
[6]: https://github.com/bjrjk/HLS-LZ77/blob/e3d81421c180502c08b35db0fbc83a652eb09947/LZ77-HLS/fifo_array.cpp#L13
[7]: https://github.com/bjrjk/HLS-LZ77/blob/e3d81421c180502c08b35db0fbc83a652eb09947/LZ77-HLS/fifo_array.cpp#L103
[8]: https://github.com/bjrjk/HLS-LZ77/blob/e3d81421c180502c08b35db0fbc83a652eb09947/LZ77-HLS/fifo_array.cpp#L171
[9]: https://github.com/bjrjk/HLS-LZ77/blob/e3d81421c180502c08b35db0fbc83a652eb09947/LZ77-HLS/fifo_array.cpp#L203
[10]: http://mux.eee.u-ryukyu.ac.jp/lecture/reconf-lecture-11.pdf