参考博客:
CSDN博主「朽月」的文章https://blog.csdn.net/zhangningning1996/article/details/107391948
本文摘要
在编写HLS代码时,各种HLS接口定义的信号令初学者很是懵逼,我自己也是,整理一下以备后续清楚地调用。
Vivado HLS需要提取控制逻辑构成状态机,因此会形成一些握手信号,比如ap_start,ap_done,ap_idle,ap_ready等。事实上,Vivado HLS还提供了其他的接口原型供选择。
接口分类
常见的接口信号基本就是定义成块(Block-Level)和端口(I/O Protocols),这两分别是对于顶层函数和顶层函数的形参来说的。每种情况又分为不同的形式如下:
默认情况下Block-Level I/O Protocols,Port-Level I/O Protocols遵循的接口协议。
顶层函数握手信号ap_ctrl
对于顶层函数握手信号ap_ctrl的设置,可是设置成三种:
1、ap_ctrl_hs:包含ap_start,ap_ready,ap_idle,ap_done四个信号。
1.1:该模块在ap_start升高之后开始操作。
1.2:在ap_start拉高之后,输出ap_idle立即变低,表示设计不再空闲。
1.3:ap_start信号必须保持高位,直到ap_ready变为高位。一旦ap_ready拉高:一、如果ap_start仍然很高,设计将启动下一个事务;二、如果ap_start被降低,设计将完成当前事务并停止操作。
1.4:可以从输入端口读取数据,输入端口可以使用独立于block-level I/O协议的端口级 port-leve I/O协议,相应的port-leve I/O协议在文章后面有相应的介绍。
1.5:可以将数据写入输出端口。输出端口可以使用独立于block-level I/O协议的port-leve I/O协议。
1.6:当块完成操作时,输出ap_done变高,如果有ap_return端口,那么当ap_done较高时,该端口上的数据是有效的。因此,ap_done信号还指示输出ap_return上的数据何时有效。
1.7:当设计准备好接收新的输入时,ap_ready信号会升高;ap_ready信号在设计开始操作之前是无效的;在非流水线设计中,ap_ready信号与ap_done同时有效;在流水线设计中,ap_start被高采样后,ap_ready信号在任何周期都可能会升高。这取决于设计是如何流水线的;如果ap_ready高时ap_start信号低,则设计执行到ap_done高时才停止操作; 如果ap_ready高时ap_start信号高,则下一个事务立即启动,设计继续运行。
1.8:ap_idle信号指示什么时候设计是空闲的、不工作的;如果ap_ready高时ap_start信号低,设计停止操作,ap_idle信号在ap_done后一个周期变高;如果ap_ready高时ap_start信号高,设计继续运行,ap_idle信号低。
上面关于时序的介绍很重要,同学们可以细读一下。如果我们只是使用,上面的信号没有那么麻烦,只需要拉高ap_start即可,至于数据什么时候输入、什么时候有效,那受相应数据的port-leve I/O协议决定。
2、ap_ctrl_none:没有任何握手信号,一般这种ap_ctrl无法得到应用。
3、ap_ctrl_chain:与ap_ctrl_hs相似,只不过比其多了一个ap_continue信号
下游块的ap_ready端口可以直接驱动ap_continue端口。第一个事务完成,第二个事务立即启动,因为ap_done高时ap_continue高。但是,设计在第二个事务结束时停止,直到ap_continue再次有效。
Port-leve I/O
1、ap_none:
默认类型,该类型不适用任何I/O转换协议,它用于表示只读的输入信号,对应于HDL中的wire类型。
ap_none接口不需要额外的硬件开销。但是,ap_none接口需要满足以下要求:
生成模块的要求:
1.1:在正确的时间向输入端口提供数据。
1.2:保持数据不变直至本次有效传输的结束
外部使用模块的要求:
1.3:使用者块在正确的时间读取输出端口
数据不可以使用ap_none接口。
事实上我们很少使用该接口协议,因为这个接口协议对外围的控制要求太高。
2、ap_stable:
只用于输入信号,其具体实现方式仍为ap_none。它用于向Vivado HLS的综合器表明该信号在两次复位之间值是不变的。
3、ap_hs:
与ap_ctrl一样包含三种协议,ap_ack,ap_vld,and ap_ovld。
ap_hs Port-leve I/O协议在开发过程中提供了最大的灵活性,允许自底向上和自顶向下的设计流。对于变量信号这是最常用的方式。
使用该类型,则会同时创建额外的数据有效信号和应答信号,其效果相当于ap_vld与ap_ack之和。
4、ap_ack:
ap_ack Port-leve I/O 协议是ap_hs接口类型的一个子集, 在数据端口port_name的基础上创建一个额外的应答信号指示< port_name >_ack。
在输出端口上使用ap_ack的设计将不能使用C/RTL协同仿真来验证
5、ap_vld
在数据端口port_name的基础上创建一个额外的数据有效信号指示< port_name >_vld。
6、ap_ovld
对于输入信号,其效果与ap_none是一样的。
对于输出信号,其效果与ap_vld是一样的。
对于双向(inout)类型的信号,输入使用ap_none,输出使用ap_vld进行处理。
7. ap_memory
把对数组的读写等效为对外部RAM的引用。
8. ap_fifo
把对数组、指针和参数引用的读写用FIFO的方式来实现。
9. ap_bus
把对指针和参数引用的读写用总线接口的方式来实现。