写在前面
本文是本系列专题的第十篇,参考高亚军老师的视频教程以及课程的ppt,主要介绍了接口综合的相关内容。
接口综合概述
块级接口协议
缺省情况下,块级接口协议被添加到设计中这些信号控制块,独立于任何端口级I/O协议。
端口级别接口协议
默认情况下,按值传递的输入参数和指针实现为简单的连接端口,没有相关的握手信号。
如果函数有返回值,则实现输出端口ap返回来提供返回值协议是ap_ctrl_hs作为返回值。
块级接口协议
块级接口协议只能在指定的函数或函数的返回值。
有三种可用的协议:
- ap_ctrl_hs:将生成Ap_start, ap_ready, ap_idle, ap_done。
- ap_ctrl_none:没有任何块级I/O协议。
- ap_ctrl_chain:类似于ap_ctrl_hs,但有一个额外的输入端口
ap_continue
,它提供从块消费这个块的数据的背压。
ap_ctrl_hs 与 ap_ctrl_none比较
ap_ctrl_hs 中的hs表示handshake(握手信号),被综合的函数为上相同的函数。如果选择ap_ctrl_hs 接口协议,则会综合出来start、done、idle、ready等接口信号。
块级接口协议信号之间的关系
- ap_start为高,表示块可以开始处理数据。
- ap_ready为高,表示块已经准备好接收新输入。
- ap_done为高,表示操作已经完成。
端口级别接口协议
ap_none:指定端口不添加I/0协议。这个端口的参数被实现为一个没有其他相关信号的数据端口。
ap none模式是标量输入的默认模式。
ap_stable模式用于只在设备处于重置模式时才会改变的配置输入。
ap_ovld与in-out参数一起使用。当将in-out分为单独的输入端口和输出端口时,ap_none应用于输入端口,ap_vld应用于输出端口。
ap_ovld:这是指针实参的默认值,可读可写。
也可以手动进行设置握手信号,在directive中,如果对in1进行设置ap_vld进行设置,则会综合生成一个输入有效信号。对in2设置ap_ack信号则会综合出一个输入响应信号,如果对信号使用ap_hs,也就是这里的in_out1则输入有效和响应信号都会产生。
接口综合支持表
在块级协议中,有ap_ctrl_hs、ap_ctrl_none、ap_ctrl_chain三种接口声明类型。
在端口协议中,默认情况下会把:
- 输入的标量、指针和参数设置成为ap_none。
- 输出通过return、输出指针和输出的参数则会默认设置为ap_vld。
- 对于输入输出的指针和参数,则会默认设置为ap_ovld。
详细分类也可参考下图:
接口综合-对数组的处理
这里对数组的处理是在顶层形参,如果是子函数的后面会进行讲解如何对数组进行优化。
在默认情况下,数组会映射成RAM端口,包含读写地址、使能等信号。
在HLS 综合工具中可以进行设置RAM为单端口和双端口。
如果不做这样的选择,Vivado HLS会自动分析设计并选择端口数量以最大化数据速率
如果指定双端口RAM, Vivado HLS可以确定只需要一个端口,它使用一个单端口,并之前设置的双端口的设置。
通过使用directives。可以设置双端口和单端口RAM接口,也可以设置使用FIFO接口。也可以进行分解数组。
存储接口
ap_memory
默认情况下,只要数组在顶级函数上,就会使用ap_memory。无论数组的类型是什么(input, output, in/out), ap_memory都是默认值。
将使用RAM接口的IP导出进行设计如下:
从上图可以看出,通常这意味着一个外部内存可用来接收来自这个块的数据,并且这个内存应该手动添加。数据的输入也同理。
ap_fifo
和RAM接口类似,FIFO接口通常也需要使用FIFO进行发送和接收数据。如下图:
数组综合小结
- 默认情况下,顶级函数上的数组将被映射到由Vivado HLS决定的单端口或双端口RAM。
- 可以根据数据速率要求对数组进行分区。
- 只要数据流,ap_fifo也是一个选项数组接口。
给输入输出端口添加寄存器
在输入输出端口添加寄存器是解决时序问题的有效办法,在默认情况下HLS攻击不会进行添加寄存器部分。
可以在指令编辑窗口中进行添加寄存器设置。
这里可以看出,根据上面的设计,综合后的结果已经生成了寄存器。
对于顶级函数,此选项与标量接口ap_none, ap _ack, ap vid, ap_ovld, ap hs相关,并导致信号(任何和协议有关的信号)被寄存并持续到函数执行的最后一个函数的执行周期。
该选项需要启用’ap_ctrl_hs’功能协议。
这个选项可以在子函数中使用,以重新调整输出和任何控制信号,直到函数执行结束。
给设计添加Global CE
默认情况下,Vivado HLS默认不会综合生成一个全局时钟。时钟使能阻止所有时钟操作,如果使能信号为低(高时刻有效)此时就可以禁用所有顺序操作。这可以通过选择目标解决方案并单击"solution setting "解决方案设置来实现。
控制IO设计的个数
这里是一个矩阵加法的示例,我们的目标是让我们的设计有更小的延时,并且有更少的IO。
此时使用pipeline指令对for循环进行展开降低了延时,但是把之前设计的单端口RAM优化成了双端口RAM。
然后可以进行使用指令对RAM接口进行约束,此时根据综合后的报告显示,相比之前的设计减少了延时,并且保证了IO的个数尽可能少。
config_rtl
config_rtl 可以帮助进行指定状态机的编码方式,同时也可以进行指定复位的属性,是同步复位还是异步复位,是高有效还是低有效。