本文是关于Xilinx HLS的简单介绍,从HLS是什么以及HLS的优点出发,进一步阐述了其功能,并针对Xilinx官方的例子对其进行了分析。关键观点包括html
- HLS采用C/C++等高级语言描述功能,能够下降FPGA代码的开发时间
- HLS的应用对象是硬件工程师,IP的架构设计依旧由工程师自行指定
- Vivado HLS提供了一套较为完整的代码开发、性能分析和优化、C/RTL仿真、IP导出流程
HLS(High Level Synthesis,高层次综合)是一种代码的综合技术,特别的,本文中描述的HLS特指Xilinx FPGA上应用的HLS。FPGA的基本知识能够从FPGA学习之基本结构获得。Xilinx的文档《Introduction to FPGA Design with Vivado High-Level Synthesis》中的两幅图能够很好的回答这一问题。算法
上图代表,虽然FPGA具备的高的性能,然而采用RTL设计FPGA代码须要较长的开发时间。编程
然而,采用HLS以后,FPGA开发的时间大大下降了,甚至可能低于DSP和GPU;这大大加速的FPGA的开发时间,使得开发具备了更强的灵活性和高效性,HLS的逐步完善使得FPGA的开发高效性更进一步。技术的发展使得人们能够把精力放在设计上,而更少的去关注底层的具体实现。架构
Vivado的HLS工具的前世此生能够从AutoESL与Xilinx那些人和事中看到,这篇文章写得颇有趣。HLS是高层次综合的的简称,“综合”即“Synthesis”,在ug627《XST User Guide》中解释综合是将程序代码翻译为称为NGC的特殊网表文件中,这样才可以对其进行实现。ide
至于“层次”,或许能够这样理解。书中通常把FPGA设计分为如下几个级别(对于这个分级实际上没有一个特定的说法,能够参考第13章抽象级别的描述):工具
通常认为RTL级及如下设计是可用的,“层次”即从什么角度去描述想要实现的功能。譬如,a xor b采用门级描述就是a,b是一个异或门的输入;而采用高一点层次描述就是a+b。显然,越低层次的描述越困难,后文例子中也能发现这一点。oop
HLS就是从高层次描述,以后综合成可用的网表文件的技术。这里的“高”指采用C、C++等编写程序,而不是传统的HDL语言。然而,实际上Vivado套件中是预先采用Vivado HLS这个软件将C程序转换成为Verilog HDL或者VHDL代码,以后进行下一步操做的,并非直接综合C代码。性能
《Vivado Design Suite Tutorial :High-level Synthesis》是一本针对Xilinx HLS的很好的入门指南。经过几个具体的例子,文档手把手的介绍了Vivado HLS的使用方式以及功能。本节将更进一步的对其进行补充学习
3.1 C代码编写优化
Vivado HLS实现的最基本的功能是将C/C++代码综合为HDL代码。因此编程使用的语言是C/C++语言。下面是其中的一个例子(代码为Xilinx例程)
1 *******************************************************************************/ 2 #include "fir.h" 3 4 void fir ( 5 data_t *y, 6 coef_t c[N], 7 data_t x 8 ) { 9 #pragma HLS INTERFACE ap_vld port=x 10 11 #pragma HLS RESOURCE variable=c core=RAM_1P_BRAM 12 13 14 static data_t shift_reg[N]; 15 acc_t acc; 16 data_t data; 17 int i; 18 19 acc=0; 20 Shift_Accum_Loop: for (i=N-1;i>=0;i--) { 21 if (i==0) { 22 shift_reg[0]=x; 23 data = x; 24 } else { 25 shift_reg[i]=shift_reg[i-1]; 26 data = shift_reg[i]; 27 } 28 acc+=data*c[i];; 29 } 30 *y=acc; 31 }
代码实现了一个FIR滤波器,输入输出关系以下式所示
和编写通常的C代码不一样,编写HLS代码依旧须要保留硬件的思想,时刻注意硬件的限制。这一点也能够从工具的名字看出,Vivado这套设计套件是提供给硬件工程师使用的。在进行C代码设计以前,咱们须要对数据从哪来,写到哪里去,计算过程当中的并行度/流水线和各种存储的访问有明确的设计。C代码实际上只是具体设计的描述,其编写方式不是随意的。
3.2 Pragma
和通常C代码不一样,HLS里有特定的Pragma来对代码进行进一步指定,这是由于从C代码中,编译器每每得不到足够的信息来完成优化工做,譬如
这一些没法在C代码中指定的内容,能够采用Pragma进行指定,以对综合过程进行更高的控制。
譬如在上述FIR滤波器的例子中,可使用采用更多的资源进行乘加操做,以达到更高的性能,同时对存储进行设计以防止访存的冲突,具体的pragma为
#pragma HLS UNROLL
#pragma HLS ARRAY_PARTITION variable=shift_reg complete dim = 1
3.3 性能分析
能够在综合后的报告中对Performance进行评估,也能够在Analysis窗口进行其调度的进一步分析,以判断性能是否知足预期,以下图所示
能够看到当了UNROLL LOOP操做后,吞吐量获得了提高(solution3 v.s. solution1)。上述优化以吞吐量为目标的,利用流水结构以及Unrolled loop能够优化吞吐量,缘由以下图所示
3.4 C/RTL仿真
在HLS中进行仿真较为简单,采用testbench完成c语言的仿真后,RTL的仿真过程可由综合器自动完成,点击按钮便可。也可具体查看仿真波形。
3.5 导出IP
略
ug902《Vivado Design Suite User Guide:High-level Synthesis》
ug871《Vivado Design Suite Tutorial :High-level Synthesis》