
一、ap_ctrl_none经典场景#include hls_stream.hvoid task_a(hls::streamint in_fifo, hls::streamint out_fifo) {#pragma HLS inline offint val in_fifo.read(); // 阻塞读out_fifo.write(val * 2); // 阻塞写}void task_b(hls::streamint in_fifo, hls::streamint out_fifo) {#pragma HLS inline offint val in_fifo.read();out_fifo.write(val 5);}void top_function(hls::streamint in_stream, hls::streamint out_stream) {// 1. 顶层禁用控制信号 (ap_ctrl_none)#pragma HLS interface ap_ctrl_none portreturn// 2. 内部使用 Dataflow#pragma HLS dataflow// 内部连接流hls::streamint internal_fifo;#pragma HLS stream variableinternal_fifo depth2task_a(in_stream, internal_fifo);task_b(internal_fifo, out_stream);}二、ap_ctrl_none使用注意问题1.必须有无阻塞或阻塞型 I/O由于没有 ap_start如果输入接口不是流式的例如是 AXI4 memory mapped 的 m_axi设计可能会在启动时死锁因为没有信号告诉它何时开始读取内存。2.死锁风险如果 Dataflow 内部的任务之间形成环路且没有使用正确的 PIPO 或 FIFO 深度很容易死锁。三、ap_ctrl_none应用场景1.ap_ctrl_none 适用于纯数据流驱动、无需外部启动/完成握手的连续处理场景2.主要包括四类--Vitis 自由运行内核free-running kernelvoid increment(hls::streamint input, hls::streamint output) {// 内核一上电即运行无 ap_start/ap_done#pragma HLS interface ap_ctrl_none portreturn#pragma HLS interface axis portinput#pragma HLS interface axis portoutputint val input.read(); // 阻塞读无数据时停顿output.write(val 1);}--连续流式流水线infinite loop stream I/Ovoid top(hls::streamap_axiu32 in, hls::streamap_axiu32 out) {#pragma HLS interface ap_ctrl_none portreturn#pragma HLS interface axis portin#pragma HLS interface axis portout#pragma HLS pipeline II1while (1) {ap_axiu32 v in.read();v.data v.data * 2;out.write(v);}}--纯组合逻辑块--以及 Dataflow 区域内仅通过 FIFO 通信的子区域void top(hls::streamint in, hls::streamint out) {#pragma HLS interface ap_ctrl_none portreturn // 顶层#pragma HLS dataflowhls::streamint s1, s2a, s2b;producer(in, s1); // 快速分发worker_a(s1, s2a); // 两个慢速消费worker_b(s1, s2b);merger(s2a, s2b, out);}