姓名:王建伟 19020100374
转载自:https://zhuanlan.zhihu.com/p/382084434
【嵌牛导读】:HLS:硬件开发软件化
【嵌牛鼻子】:硬件开发软件化
【嵌牛提问】:HLS:硬件开发软件化
【嵌牛正文】:
一、前言
记得很久以前,一个学长给我说过:那些搞软件的之所以可以写出那些屎一样的代码,就是我们搞硬件的人“供”起来的。虽然这话或许不一定全对,但是软件和硬件的发展就是这样一种“相爱相杀”的关系:按照摩尔定理,集成电路上可以容纳的晶体管数目在大约每经过18个月便会增加一倍,于是硬件平台的算力可以得到倍增。但是,软件也越会变得越来越臃肿,因为平台算力增加了,它可以吃的红利变多了。从最开始,软件开发只能使用汇编语言,然后出现C语言,再到出现C++、Java、Python这些更高级的语言。从面向过程编程,到面向对象编程。从所有程序都得自己写,到可以直接调用各种各样的库。软件发展的逻辑就是降低开发成本,让软件开发变得更容易,但是这也是以牺牲效率为前提的。
图1 软件高级语言的发展历程
安卓的发展就是这一现象完美的研究样本,因为安卓手机是2008年10月才出现的,国内的话会更晚一点,我们很多人都经历了安卓从无到有的发展过程。在2012年,我买了自己第一个安卓手机,我记忆很深刻,当时qq就10MB左右大,很轻简。但是,到如今,一个qq的大小早就超过100MB了。伴随着这一过程中,手机芯片也从高通MSM7200A发展到了高通骁龙888,手机芯片能提供的算力不知道翻了多少倍了。这也是软件得以变得越来越大,可以实现更多功能,以及可以在手机运行更大体量的游戏的根本前提。
二、什么是硬件开发软件化
但是,我们今天要讨论的主题其实不是“批判软件是如何吃硬件提供的红利的”,我们要讨论的是“硬件开发软件化”这一现象。什么是硬件开发软件化?这一概念可能对非微电子的学生来说,是非常陌生的概念,因为很多人不知道什么是硬件开发。在这里,因为现代的芯片,绝大部分的电路都是数字电路,所以我们这里讨论的硬件开发主要就是指数字电路设计。对于传统的硬件开发,是使用Verilog/VHDL这种HDL语言,来搭建起RTL级电路,然后综合工具可以将这些代码转换成数字电路,再生成版图,最后经过台积电这种Foundry“流片”后,才能得到实体的芯片。
但是,HDL语言是比较难学的,它本质上只是一种硬件描述语言。这跟软件是完全不一样的,因为软件语言是逻辑语言,理论上你只要懂一点逻辑,就能写出可用的软件代码。对于HDL语言来说,你必须“心中有电路”,才能写得出对应的HDL代码。你必须考虑时序,考虑并行,考虑延时,考虑资源占用,否则你写出来的代码将是一种灾难。在这种情况下,为了降低硬件开发的门槛,开始有人想到,能不能不用写Verilog/VHDL代码,直接使用C/C++、Python这些高级语言综合出Verilog或VHDL代码,从而简化硬件设计,降低硬件设计的门槛,这种思想就是高层次综合(HLS)。
图2 Vivado HLS设计流程
HLS近几年开始变得很热门,主要原因还是因为AI的发展,让设计神经网络加速器开始变成一种潮流。这是计算机/软件等专业的人大多是不懂HDL语言的,但他们懂C/C++、Python这些高级语言,这样他们使用HLS就可以避免去学习数字电路设计的专业知识,可以极大地降低他们开发神经网络加速器的门槛。正因为如此,HLS开始在计算机/软件等专业流行起来。但是,HLS综合出来的HDL代码不总是高效的,为了提高综合出来的代码的质量,必须得使用很多优化手段。拿C语言来说,在使用多种优化手段后,C语言会变得特别奇怪,跟平常写的C语言会有非常大的区别,会非常的不像C语言。
三、高层次综合(HLS)
HLS这个概念其实出现得很早,在19世纪80年代就已经出现了,但是因为技术难度很大,20多年一直没有得到太大的发展。在2003年,Zhiru Zhang进入UCLA读博,他的导师Jason Cong给他选了HLS方向的课题,博士课题就叫做:Behavior-Level Scheduling and Planning for Nanometer IC Designs。最后,他成功地实现了非时序代码的时序硬件化,极大地推动了HLS的发展。在2006年,他在拿到博士学位后,与导师一起创立了AutoESL公司,专注于C语言转HDL语言的研究。在2011年,这家公司被Xilinx收购,从此就有了Vivado HLS。与此相对的是,另一大FPGA厂商Altera也开发了自己的HLS工具,也就是OpenCL,只不过因为工具链没有Xilinx成熟,没有Vivado HLS那么流行。在2015年英特尔收购Altera后,Quartus+Modelsim这套工具链也被整合进英特尔的开发生态中。
HLS很长一段时间都不被人重视,这是因为:搞硬件的会写Verilog/VHDL,不会用它;搞软件的没有理由用它。虽然Xilinx在2010就推出了“硬核CPU+FPGA”架构的ZYNQ平台,但它一直没有找到合适的应用场景,所以刚开始市场普遍都不是很看好它。然而,在2012年AlexNet的出现后,深度学习开始进入了发展的快车道,在全球刮起了新的AI热潮,有些高校的课题组就开始想到使用ZYNQ来fit神经网络加速器。虽然HLS综合出来的HDL代码效率不高,但是相比于串行执行软件代码的CPU来说,FPGA加速器并行执行的速度要快得多;而相比于GPU,虽然FPGA加速器速度比不了GPU,但它又具有功耗优势。正是靠着与CPU比速度,与GPU比功耗,围绕着FPGA加速器出现了不少论文。
图3 具有DNN加速器的SoC
后面为了进一步提高能效比,大家又开始转向直接使用Verilog/VHDL语言来设计FPGA加速器。但是,因为神经网络的规模越来越大、结构越来越复杂,使得直接进行设计RTL级设计,变成了一个非常浩大的工程。在这种情况下,HLS因为能极大地减小工作量,所以依然不能完全被取代。而且如果以后能够进一步提高HLS的效率,被淘汰的可能反而会是Verilog/VHDL语言。当然,这一天可能还很遥远。现目前的情况是,微电子专业的人更倾向于直接使用Verilog/VHDL语言来fit轻量级的神经网络,比如MobileNet、SequenceNet;而计算机/软件专业的人更倾向于使用HLS来fit更大型的神经网络。当然,这不是绝对的,因为很多计算机/软件的人不会碰硬件设计,而不少微电子的人也用HLS。
四、ARM的CMSDK
什么是CMSDK?它其实是ARM DesignStart计划推出的一个新IP集,里面提供了常用的UART、SRAM等IP,最重要的是提供了1个可以自动生成总线矩阵的脚本工具。事实上,ARM在2017年6月20日就开源了Cortex-M3核,但是那时还没有推出CMSDK,所以那时我们进行基于Cortex-M3的SoC开发,必须得自己安照总线协议来手写总线矩阵,而且总线上挂的模块也只有自己写,没有现成的Verilog模块可用。但是,在2020年,ARM推出了CMSDK,我们可以直接使用脚本工具生成总线矩阵的Verilog代码,而且UART、SRAM等模块也可以直接调用ARM给的Verilog模块即可。于是,我们可以避免在搭建系统的总体结构上浪费时间,而把更多的时间用到神经网络加速器这些专用模块的设计上。
图4 ARM DesignStart计划
关于如何使用脚本工具生成总线矩阵,以及如何使用CMSDK中的IP,我这里就不做介绍了。感兴趣的人,可以去看看知乎大佬Teation Zhao写的教程。Teation Zhao对ARM SoC有多年研究经验,而且他们最近要出一本书,手把手教学如何进行ARM SoC开发,大家可以关注一下。我们现在要讨论的是,这个脚本工具其实也是一个HLS工具,只是它是把脚本代码转换成Verilog代码。某种意义上说,这其实比C/C++、Python转HDL代码更“高层次”,因为我们只需要描述总线的连接关系和地址分配,就能生成对应的总线矩阵模块。但是,它的局限性也很大,它只能用于生成总线矩阵。
但是这为我们提供了一种思路,也就是设计很多个工具,而每个工具都专用于生成某种模块的RTL级代码。比如总线矩阵,我们可以用CMSDK的脚本工具来生成RTL级代码。对于CNN加速器,因为CNN主要就是卷积层、全连接层等,我们可以分别设计卷积层综合工具、全连接层综合工具,来生成高效的卷积层、全连接层的Verilog模块,再把它们连接起来即可。事实上,这种工作确实有人在做,比如UI的Xiaofan Zhang在2018年提出的DNNBuilder,就是专用于生成DNN加速器的工具,它生成的加速器拥有现时最先进的性能和效率,超越了同类加速器。
图6 DNNBuilder
这不由得让人遐想,如果有一天,工具链真的可以细分到非常小的程度,各种模块都有特定的综合工具,那么生成各种高效的Verilog模块都将成为现实。也许到那一天,人类手写的Verilog/VHDL代码将不如机器生成的代码高效——这就是硬件开发软件化的未来。正如很多硬件开发人员抱怨那样,Verilog/VHDL几十年来就没什么进步,一直都没有出现更高级的设计语言。相比于软件语言的百放齐放来说,硬件语言确实宛如一潭死水,但这是硬件开发的特殊性所决定的。未来会怎么样呢?谁知道呢,但社会总会是进步的。