分为4层:
1 ap_ctrl_no、ap_ctrl_hs、ap_ctrl_chain,主要确定当前kernel的工作模式
2 驱动并行模型
1) 数据驱动并行模型,HLS::task
2)控制驱动并行模型,dataflow
3) 混合驱动并行模型
驱动并行模型的作用是确定生产kernel的基本并行电路,或者说确定好模型基本就确定了电路的布局,剩下就剩下要不要流水打拍了。
在kernel中,先不考虑循环(只考虑循环中的一次代码执行),这种情况下执行流程总体是c++代码顺序执行的,这种就是控制驱动(代码流程“控制“了整个流程);如果用task来写,即使代码交换位置也能正常执行(毕竟task只依赖输入,顺序调换下没关系);混合就是两个结合起来
驱动并行模型核心是并行,主要目的是怎么让执行流程并行起来,形成并行的电路,最终达到利用fpga并行的作用。
dataflow是在ap_ctrl_chain的基础上,严格按照c++代码的流程的基础上,尽可能提供并行度来完成的
task仅仅根据输入 输出决定如何执行,整个过程不受外界干预(因此它一定是ap_ctrl_no的方式),因此在设计的时候可以方便的控制并行。
驱动并行度和pipeline的关系
pipeline是流水打拍,可以理解为再已经生成的电路上形成“浪涌“,即整个流程没执行完成前,再次提前启动,因此流水打拍一定是多次执行有效,所以一定要在循环中(上面讲到的只考虑循环中一次的并行设计,本质上对整个流程进行切割成不同部分,再外围循环中执行,每个部分可以单独pipeline,最终做到不同部分执行不同次循环执行的目的)。
总体上说驱动并行是解决一次执行中的并行度的问题;流水打拍是为了解决循环中多次执行并行的关系。
3 数据结构和算法
数据结构和算法是软件中的概念,借用到这里是为了描述硬件优化的两个重点。
数据结构:
数据结构优化:主要分为阵列(软件中的数组)和结构体。
对于阵列可以进行聚合(聚合成单一位宽)、解聚(分成多个单节点),重组等,从而达到对阵列操作性能和资源的平衡(硬件和软件一个很大区别在于资源不够,否则都可以像软件那样按照最优来就好了,也没必要搞出那么多模式)
结构体也是硬件中常用的方式,其中对结构体操作也有聚合、解构等,目的仍然一样
变量相关:比如dependce可以告诉编译器两个变量间是否相关;stable告诉编译器参数可以随时读写,不需要考虑dataflow或pipeline是否完成。
算法部分:
算法部分有很多优化可以用,其中主要包括对循环相关的、执行流程控制等
4 底层相关
主要是硬件底层存储结构相关,包括寄存器、ram、全局存储器等