基于Mentor Graphics Catapult工具的HLS硬件设计

描述

本文介绍基于Mentor Graphics Catapult工具的HLS(High LevelSynthesis,高层次综合)硬件设计。

硬件设计

首先将简单介绍高层次综合在数字芯片流程中所处的层次、其独特优势等等;接着将介绍如何基于Catapult工具进行HLS设计,例如Catapult支持的数据类型、接口类型;最后将以RMD(RoughMode Decision,粗略模式估计)为例介绍如何实现寄存器、状态机和RAM等硬件电路基本组件。

硬件设计

如图表所示,数字芯片的硬件描述层级可以被粗略分为四个,从底向上依次是物理级(晶体管级)、门级、RTL(RegisterTransfer Level,寄存器传输级)级和系统级/算法级。随着芯片复杂度(晶体管数量)的不断提升,在较低层次上描述整个硬件设计变得难以实现。目前的数字芯片集中于在RTL级以Verilog/ System Verilog语言描述硬件电路,特殊情况下为了追求极致的性能可能会在门级/物理级进行电路设计。总体来说,主要依靠DC(DesignCompiler), ICC(ICCompiler)这样的EDA(ElectronicsDesign Automation,电子设计自动化)工具来实现硬件描述层次的降低。随着EDA工具的不断发展,在系统级/算法级使用C/C++/SystemC等高级语言描述硬件电路逐渐被厂商采纳以提升硬件开发效率。即在DC和ICC前,再使用HLS的综合器来实现硬件描述层次的降低。

硬件设计

HLS的出现,让硬件描述层级再次提升,有利于降低硬件设计难度,减少硬件开发时间,让开发人员可以更多关注系统级/算法级的设计。越高层次的优化往往能带来更多的系统收益。但需注意,使用C等高级语言描述硬件电路本质仍是设计硬件,在写相关代码时仍需做到能估计出相关的硬件电路。在FPGA开发流程中,Vivado HLS是最常使用的HLS工具。而在ASIC开发流程中,Catapult是最常使用的。

硬件设计

HLS在设计和验证方面都存在诸多优势:

在设计方面,直接在算法级进行电路设计,有利于进行算法/架构探索。C/C++代码开发后通过HLS+DC/FPGA快速得到硬件代价(面积/性能)的估计值。相同的设计源码,通过更改循环展开/循环流水的参数能快速调整设计的吞吐率,进而在性能和面积之间轻松调整;通过调整HLS的时钟周期约束,能快速调整设计所能达到的最高频率。同一份代码,能在多个平台/场景间最大化复用。

在验证方面,仿真C模型后能将其作为golden,和后续HLS生成的RTL代码进行形式验证,以及同步仿真,即RTL仿真时复用C仿真的测试用例。此外,在C模型层次仿真所需时间更少。

硬件设计

高层次综合和DC综合过程较为相似:用户输入设计源文件,设计约束和目标工艺库等信息,HLS工具将自动分配硬件资源,根据延时信息和目标频率将各个运算分配到各个时钟周期里。HLS工具将自动插入时钟和复位(同步复位/异步复位)。产生的RTL文件可以被用于后续的FPGA设计和ASIC设计。

硬件设计

Catapult有一系列EDA工具来辅助HLS设计:

在C模型(CMODEL)层次,可以使用C Design Checker来进行语法检查和形式验证分析;使用inFactStimulus来仿真C++/RTL,也可指定其他外部仿真工具如VCS;使用CCOVHLS-Aware Coverage来进行覆盖率收集。

在CMODEL到RTL模型(VMODEL)转换中,使用Catapult High-Level Synthesis生成高质量、功耗优化的RTL。

在VMODL层次,使用SLEC-HLS Formal进行C++和RTL的形式验证检查;使用SCVerify进行C-RTL同步仿真,复用相同的C测试用例。

硬件设计

在RTL设计中,以模块(Module)为最小单元进行硬件设计。在CatapultHLS设计中,支持以函数(function)和类(Class)作为最小单元进行设计,HLS综合工具将为其自动插入时钟和复位。

硬件设计

Catapult HLS支持比特精度的数据类型ac_int, 通过设计位宽W 和符号标志位 S来定义信号。此外,其还支持定点数类型ac_fixed,在ac_int的基础上新增整数位宽I。

硬件设计

Catapult HLS使用 ac_channel 来定义输入端口和输出端口的数据类型。若某端口只被读取,则将其推导为输入端口;若某端口只被写入,则将其推导为输出端口;若某端口既有读取又有写入,则会被推导为双向端口。如需进行累加,建议使用中间变量来进行累加,累加结束后再将结果写入,从而避免输出端口被推导为双向端口。

ac_channel 支持多种接口协议,输入输出默认类型为ccs_in_wait和ccs_out_wait,会自动维护ready和 valid,也可将其修改为最简洁的ccs_in/ccs_out类型。

硬件设计

Catapult HLS支持循环展开,用面积换性能,如果迭代块无数据依赖可以被完全展开。

硬件设计

Catapult HLS支持循环流水,也是用面积换性能,提升整体的吞吐率,并降低从输入到输出的延时。当存在数据依赖导致循环展开无法使用时,可以采用循环流水的方式优化。

硬件设计

对每个循环都可以指定其流水与否,II(InitInterval)确定了流水线的初始化间隔,即每隔几个周期开启一次新的数据迭代。

硬件设计

可以通过在源码中加入诸如 #pragaunroll yes的指令来设置约束;也可以通过tcl指令在脚本中设置约束,诸如设置RMD的预测模块(enc_rmd_pre)采用流水实现。

硬件设计

此外,还可以通过软件的图形界面来进行设置约束,即在各个综合步骤(SynthesisTasks)中设置相关的约束。在图形界面进行设置后,transcripthistory里会显示对应的tcl 指令,可将其搜集起来汇总到脚本中,后续复用。修改源码/配置后可以产生新的Solution,工具会显示各个Solution的延时、吞吐、综合面积和时序裕量。

硬件设计

以RMD模块为例介绍HLS设计,其包含了控制、参考像素管理、帧内模式预测、残差计算、SATD代价计算和模式排序与输出等等子模块。使用HLS实现各个子模块,使用verilog进行顶层设计。RMD将流水处理4个PU,对每个PU会进行7种模式预测。流水线启动延时为12个周期,后续4*7=28个周期逐渐出结果。

硬件设计

采用基于类的方式来实现模块设计。定义__ENC_RMD_CTL_H__这个宏以避免多重编译。define.h中定义了诸如块尺寸和位宽的一些参数,以及封装了一些常用的数据类型,比如AC_UINT(x)即 ac_int。使用#pragmahls_design top 指定顶层函数。使用const修饰一些常量参数,使用static来描述寄存器(registers),或者也可使用类的成员变量来描述registers,使用AC_UINT(x)来描述网线(wire)。

将状态跳转条件和输出置于状态变量(计数器 cnt_mod/pu,状态机state)更新之前,即当前输出与之前的输入和状态变量相关,摩尔型。

硬件设计

以Planar预测模式为例,其将根据上方、左方和左上方的参考像素来得到当前块的预测值,pxl_t是封装了ac_int<8,false>。对两重循环使用#pragmahls_unroll yes进行循环展开。定义相应位宽的中间变量来记录中间结果,避免被截断。对于这类纯计算函数,无需手动切流水级,工具将根据目标工艺和时钟约束来自动调度,使得各个周期内的运算延时较为均匀。

硬件设计

在非顶层函数的接口中可以使用数组来简化后续索引。为此,在顶层函数的输入和输出处需增加平面格式与多维数组格式的数据格式转换,可使用slc和set_slc进行切片操作。

硬件设计

对于参考像素管理中需要使用到的行缓存,register实现时代价过大,倾向于使用ram实现。为此,1. 使用 static修饰该数组;2. 如果不需要将数组/ram初始化为0,则设置该数组的初始化类型为AC_VAL_DC,即 Don’tCare,以避免工具默认对ram进行初始化为0的操作,节省若干启动周期。3. 在设置目标库时增加相应的ram库,如ccs_sample_mem。此外,可以通过tcl指令来指定某些数组的默认类型,例如将buf_hor_lin_rd 强制设置为Register类型。

审核编辑 :李倩

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分