写在最前:
接口对应的是资源,端口对应的是协议和服务,端口只能按照固定的协议提供服务,接口必须通过端口才能实现资源调用
对于Vivado HLS,当顶级函数被综合时,函数的参数被综合为RTL端口,这个过程就称为接口的综合,而这个过程就需要使用I/O协议。
接口综合实例分析
注:(以下代码提供了接口综合的全面概述)
#include "sum_io.h"
dout_t sum_io(din_t in1, din_t in2, dio_t *sum)
{
dout_t temp;
*sum = in1 + in2 + *sum;
temp = in1 + in2;
return temp;
}
以上示例包括:
1)两个按值传递的输入in1和in2
2)读取和写入的指针sum
3)函数返回temp的值
使用默认接口综合设置,设计将综合为RTL块,其端口如下图所示:
可见,Vivado HLS在RTL设计中创建了三种类型的端口:
1)时钟和复位端口:ap_clk和ap_rst
2)块级接口协议,在上图中展开为:ap_start,ap_done,ap_idle和 ap_ready
3)端口级接口协议, 这些是为**顶级函数中的每个参数和函数返回(如果函数返回一个值)**创建的 :in1,in2,sum_i, sum_o,ap_return 和sum_o_ap_vld
时钟和复位端口
如果设计需要超过1个周期才能完成操作时:
1) 一个芯片使能端口可以选择被添加到整个块中通过使用Solution>Solution Settings>General和config_interface 的操作
2)复位操作由config_rtl控制
块级接口协议
默认情况下,块级接口协议将被添加到设计中,这些信号独立于任何端口级I / O协议。
这些端口控制块可以开始处理数据(ap_start),指示何时准备好接受新的输入(ap_ready),并指示设计是正在空闲(ap_idle)还是已完成操作 (ap_done)
端口级接口协议
创建的I / O协议取决于C参数的类型和默认值。
1)在使用块级协议开始块的操作之后,端口级IO协议被用于将数据按顺序输入输出块。默认情况下,输入值传递参数和指针被实现为简单的线端口,而没有关联的握手信号。在上面的例子中,输入端口因此可以在没有I / O协议的情况下实现,但仅是数据端口。
2)如果端口没有I / O协议(默认或设计的情况下),则输入数据必须保持稳定,直到被读取。
3) 默认情况下,输出指针使用相关的输出有效信号实现,以指示输出数据何时有效。- - 在上面的示例中,输出端口使用关联的输出有效端口 (sum_o_ap_vld)实现,该端口指示端口上的数据何时有效并且可以被读取。 - - 如果没有与输出端口关联的I / O协议,则很难知道何时读取数据。 在输出上使用I / O协议总是一个好的想法
4)读取和写入的函数参数将拆分为单独的输入和输出端口。- - 在上面的例子 中,sum被实现为输入端口sum_i和输出端口sum_o以及相关的I / O协议端口 sum_o_ap_vld - -
5)如果函数有返回值,则输出端口ap_return被实现去提供返回值。 当执行完一次C函数后,块级协议的ap_done信号表明函数已完成 , 这也表明端口ap_return上的数据是有效的且可以读取。
注意:顶级函数的返回值不能是指针。
对于上面的示例代码,时序行为如下图所示(假设目标技术和时钟频率允许每个时钟周期单次添加):
1)当ap_start声明为高时,设计开始
2)ap_idle信号置为低电平表示设计正在运行
3)在第一个周期后的任何时钟读取输入数据,则hls会在读取发生时进行调度,读取所有输入后,ap_ready信号置为高电平
4)计算输出sum时,关联的输出握手信号(sum_o_ap_vld)表示数据有效
5)当函数完成时,ap_done被声明,这也表明ap_return上的数据有效
6)端口ap_idle置为高电平表示设计正在等待再次启动
接口综合和 OpenCL API C
在综合期间,Vivado HLS将OpenCL API C中的所有接口分组如下:
1)所有标量接口和块级接口都到单个AXI4-Lite接口中
2)所有数组和指针都到单个AXI4接口中
注意:OpenCL API C内核不允许使用其他接口规范
注:本文基于Vivado 设计套件用户指南-----高层次综合,在翻译的基础上结合自己的理解与思考后整理而得