一、说明
1.ap_ctrl_none:最精简的模式,不产生任何握手信号,模块依靠数据有效信号持续工作
2.ap_ctrl_none也就是free-run模式,永动机模式
3.ap_ctrl_none的应用高度依赖于#pragma HLS dataflow指令,目的是在数据流区域中,通过消除块级握手信号的开销,让数据像流水一样无阻塞地通过各个处理阶段,从而最大限度地提高吞吐量
4.使用ap_ctrl_none后,生成的硬件模块不需要ap_start信号来启动。只要输入端口有有效数据,且复位信号无效,模块就会开始工作
5.ap_ctrl_none强制数据流区域内的所有进程必须通过FIFO进行通信。这意味着像hls::stream和标记为#pragma HLS STREAM的数组是必需的,不能使用普通的RAM或内存接口(如#pragma HLS INTERFACE bram)
6.ap_ctrl_none要求数据流区域内的所有子任务(进程)执行的总次数必须完全相同。因为握手信号的缺失,使得下游模块无法精确“背压”上游,从而可能破坏C仿真的顺序模型,而“执行次数相同”这一强约束确保了行为的一致性
7.如果一个数据流区域使用了ap_ctrl_none,其所有父级模块直至顶层,都必须同时使用DATAFLOW指令和ap_ctrl_none协议。这是因为ap_ctrl_none区域没有ap_done信号,父级FSM无法得知它何时完成,导致系统卡死
二、ap_ctrl_none使用的禁区
1.禁止在循环内部使用
绝不能在for循环内部的数据流区域使用ap_ctrl_none。HLS工具需要ap_done信号来判断循环迭代何时结束,而ap_ctrl_none不产生该信号,会破坏循环的正常执行逻辑。
2.顶层设计推荐使用ap_ctrl_hs或ap_ctrl_chain
除非满足特殊条件(如设计为纯组合逻辑或启动间隔II=1),否则不建议在顶层模块使用ap_ctrl_none。
三、要求
1.使用阻塞的hls::stream
在ap_ctrl_none数据流区域内部,必须使用阻塞式的hls::stream::read()和hls::stream::write()操作。非阻塞操作缺少必要的握手,无法保证C/RTL协同仿真的成功。
2.AXI4-Stream是绝配
输入输出端口采用AXI4-Stream接口(即#pragma HLS INTERFACE axis)是与ap_ctrl_none配合的极佳选择。AXI4-Stream本身就是为连续数据流设计,它的tvalid和tready握手信号与ap_ctrl_none的数据驱动模型天然契合。
四、ap_ctrl_none的本质
1.在Vivado HLS的数据流(DATAFLOW)中使用 ap_ctrl_none,是一种为追求极致性能而剥离顶层控制接口的高级用法。它本质上是对工具的承诺——设计中的数据流进程将执行完全相同的次数,以此来换取硬件实现上更低的资源开销和更高的吞吐效率。
2.对于视频、网络包处理、数字信号处理(DSP)等数据连续输入的应用,使用 ap_ctrl_none 可以避免 ap_start/ap_done 等握手信号的开销,让模块一旦上电即持续运行,最大化吞吐量
3.纯组合逻辑或完全流水化设计:如果设计是纯组合逻辑,或能在每个时钟周期都处理一个数据(即启动间隔 II=1),使用 ap_ctrl_none 可以消除块级握手信号,使模块运行更加高效