如何在Vivado HLS IP中生成可观测的二进制触发信号
问题
我希望为我的Vivado HLS IP添加一个用于测量的二进制触发信号,代码如下:
void subfunction1(const int a[10], const int b[10], int out[10]){ for(int i=0;i<10;i++){ out[i] = a[i] + b[i]; } } void subfunction2(const int a[10], const int b[10], int out[10]){ for(int i=0;i<10;i++){ out[i] = a[i] + b[i]; } } void function(const int a[10], const int b[10], int out[10], bool *trigger){ subfunction1(a, b, out); *trigger = true; subfunction2(out, b, out); *trigger = false; } uint8_t top_level_fun(const int a[10], const int b[10], int out[10], bool *trigger){ #pragma HLS INTERFACE ap_memory port = a #pragma HLS INTERFACE ap_memory port = b #pragma HLS INTERFACE ap_memory port = out #pragma HLS INTERFACE ap_fifo register port = trigger #pragma HLS RESOURCE variable=a core=ROM_1P_BRAM #pragma HLS RESOURCE variable=b core=ROM_1P_BRAM #pragma HLS RESOURCE variable=out core=RAM_1P_BROM function(a,b,out,trigger); return 0x01; // success }
我期望trigger变量默认值为0,在subfunction2执行期间为1。但编译/联合仿真后,在全波形查看器中发现trigger的值从未变化,请问如何控制该变量的值,使其在IP顶层可观测?
解决方案
问题根源
Vivado HLS的优化器会判定*trigger = true和*trigger = false之间没有可被外部观测的时间窗口,直接将这两个赋值操作合并优化,导致trigger信号始终保持初始值。另外,ap_fifo接口类型不适合这类单比特电平触发信号,FIFO需要严格遵循读写时序,而你需要的是一个可直接驱动的输出端口。
修改步骤
调整trigger的接口类型
将trigger的接口从ap_fifo改为ap_none(纯组合/寄存器输出)或ap_vld(带同步有效信号),同时保留register属性确保信号被寄存器打拍输出:#pragma HLS INTERFACE ap_none register port = trigger阻止HLS优化trigger的赋值逻辑
- 给
subfunction2的循环添加流水线约束,让HLS识别到该函数需要多个时钟周期执行,无法合并前后的trigger赋值:void subfunction2(const int a[10], const int b[10], int out[10]){ #pragma HLS PIPELINE II=1 for(int i=0;i<10;i++){ out[i] = a[i] + b[i]; } } - 或者针对
function函数关闭激进优化,避免赋值被合并:void function(const int a[10], const int b[10], int out[10], bool *trigger){ #pragma HLS OPTIMIZATION_LEVEL off subfunction1(a, b, out); *trigger = true; subfunction2(out, b, out); *trigger = false; }
- 给
显式初始化trigger默认值
在顶层函数开头添加初始化代码,确保trigger初始值为0:uint8_t top_level_fun(const int a[10], const int b[10], int out[10], bool *trigger){ *trigger = false; // 显式设置默认值 // ... 原有代码 }调整综合优化策略
如果使用了-O3等激进优化等级,可以适当降低到-O1或-O2,或者在项目设置中禁用"Remove Unused Logic"类的优化选项,确保trigger的赋值逻辑被保留。
验证方式
修改后重新执行C仿真、综合和联合仿真,在波形查看器中检查:
- trigger初始值为0
- subfunction2执行的10个时钟周期内,trigger维持高电平1
- subfunction2执行完成后,trigger变回0
内容的提问来源于stack exchange,提问作者Trick
相关产品推荐
相关产品推荐

