高层次综合

高层次综合(High-Level Synthesis, HLS)目标是将高级编程语言(High-Level Languages, HLL)编写的程序转化为硬件描述语言(Hardware Description Language, HDL)的程序。

简介

主要分为以下几个步骤。

graph TD; A["HLL (C/C++)"] --> B["Allocation"]; B --> C["Scheduling"]; C --> D["Binding"]; D --> E["HDL (Verilog/VHDL)"];
  • 分配(Allocation):确定必要的硬件资源(几个加法/乘法/寄存器)
  • 调度(Scheduling):每一个时间周期内应执行什么操作
  • 绑定(Binding):将硬件指派到每一个操作上

注意与传统编译不同,硬件描述语言并不用于编程,它直接描述了硬件电路。

时刻记住:FPGA是并行结构,编译出来的程序用于描述电路

  • 但关于并行其实与CPU的差异并没有那么大,现在大多CPU都支持指令级并行(instruction level parallelism, ILP),静态并行由编译器完成,动态并行由处理器完成
  • 相对于传统编译可能是限制比较多

高层次综合的优势

  • 自动实现高级语言到硬件语言的转换,使软硬件工程师可以在同一层面交流
  • 针对软件工程师数量远大于硬件工程师的现状,HLS使软件工程师也可以参与到硬件开发中来
  • 通过优化,设计出占用资源更少、运算速度更快的硬件
  • 开发硬件更加高效,容易编写,少bugs,容易维护,贴近自然语言,可读性高

高层次综合目前存在的问题

以下这些问题是Jason Cong于2011年在[3]中提到的,目前已经逐步被解决

  • 缺少高层更加可理解的(comprehensive)设计语言支持
  • 缺少重用便携的硬件规格(specificaiton)
  • 仅仅关注于数据流综合
  • 缺少满意的QoR:算法优化目标并非实际上板目标,因此最终实施经常会无法满足时序/功耗限制
  • 缺少一个质变的转折点去采用新的设计模式

高层次综合目前不支持的特性

能够被综合到硬件上的程序必须给定所有需要的资源

  • 系统调用(system call)
  • 动态内存分配:运行时操作系统分配
  • 指针不行,数组可以
  • 递归函数

高层次综合与传统编译的区别

  • CPU/GPU都是冯诺依曼架构,需要指令译码并执行(Assembly/PTX);而FPGA是非冯/并行架构,不需指令,要做的就是用硬件描述语言将电路图描述出来
  • CPU/GPU都是用于通用计算,内部电路已经确定,指令即算什么,其流向是已经确定的;而FPGA实际上涉及到设计(how)计算(what)两个方面,设计回答的是怎么算(how)的问题,计算则回答算什么(what)的问题(这与当前领域特定语言的设计趋势是一致的)

    开文讲CPU/GPU架构

  • 那高层次综合其实就包括这两个方面,一个是设计,另一个是计算。
    一个简单的程序你首先要先将电路图描绘/设计出来映射到板上,然后再从片上内存读入数据(testbench)进行计算
    即在原始程序中需要包含算法输入两个部分。(针对异构系统另说)
  • 因而目前FPGA的设计(对应于DSL的调度策略)是计算导向的(确实应该是这样,有需求才有供应/如果反过来先供应后需求,那是Chisel-Rocket走的路)
  • 如果将设计和计算剥离开来,那编译器的实施会好做很多,Spatial就是这么来的(隐性实现)
  • 由上,FPGA编译的重点在于设计,与传统CPU/GPU面向计算的编译不一样,因而TVM也要专门为FPGA开辟一条路,先设计好硬件加速器VTA,然后通过运行时系统(JIT)实现CPU+VTA的异构计算

上层建筑

要提高高层的生产力,目前有两条路子可以走

  • 一条路是重新发明新的HDL或高层抽象,规范好新的语言特性后,重新从这些语言开始编译优化成为Verilog
  • 另一条路则是传统的高层次综合,由固有的高级编程语言/程序(C/C++)编译到Verilog
    • 对,这里要说的是,C HLS依然重要!尽管C/C++并非面向FPGA,因而编程语言固有的劣势无法避免(如无法并行、无法显式控制内存、时序等,这些都是需要编译器自己设计/推断的),但是大量应用(如数值计算、图像处理、嵌入式系统)都用C写(加上OpenMP/Clik)。为了避免这些领域的工程师重新学一门新的语言,并将原有程序改写,能够实现不做过多改动的端到端的编译当然是最好的
    • 最终目标是C的工程师不需做任何改动就可以生成高效的硬件实现,这对编译器的要求就很高(要不然编译器做得很激进,要不然语言要做出妥协)

底层设施

针对大量的重复的任务,一次性编译重复使用(reusable),这时一次编译时间长点倒没有关系(这是pynq的做法)。

  • 针对复杂循环,ElaticFlow
  • 针对并行程序,TAPAS
  • 针对图,…
  • 针对数值,…

参考文献

  1. Steven Margerm (Simon Fraser University), Amirali Sharifian, Apala Guha, Arrvindh Shriraman, Gilles Pokam, TAPAS: Generating Parallel Accelerators from Parallel Programs, MICRO, 2018
  2. Mingxing Tan (Cornell), Gai Liu, Ritchie Zhao, Steve Dai, Zhiru Zhang, ElasticFlow: A Complexity-Effective Approach for Pipelining Irregular Loop Nests, ICCAD, 2015
  3. Jason Cong, et al., High-Level Synthesis for FPGAs: From Prototyping to Deployment, TCAD, 2011
  4. Xilinx, Vivado Design Suite User Guide - High-Level Synthesis (v2018.3), 2018