You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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需要严格遵循读写时序,而你需要的是一个可直接驱动的输出端口。

修改步骤

  1. 调整trigger的接口类型
    将trigger的接口从ap_fifo改为ap_none(纯组合/寄存器输出)或ap_vld(带同步有效信号),同时保留register属性确保信号被寄存器打拍输出:

    #pragma HLS INTERFACE ap_none register port = trigger
    
  2. 阻止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;
      }
      
  3. 显式初始化trigger默认值
    在顶层函数开头添加初始化代码,确保trigger初始值为0:

    uint8_t top_level_fun(const int a[10], const int b[10], int out[10], bool *trigger){
      *trigger = false; // 显式设置默认值
      // ... 原有代码
    }
    
  4. 调整综合优化策略
    如果使用了-O3等激进优化等级,可以适当降低到-O1或-O2,或者在项目设置中禁用"Remove Unused Logic"类的优化选项,确保trigger的赋值逻辑被保留。

验证方式

修改后重新执行C仿真、综合和联合仿真,在波形查看器中检查:

  • trigger初始值为0
  • subfunction2执行的10个时钟周期内,trigger维持高电平1
  • subfunction2执行完成后,trigger变回0

内容的提问来源于stack exchange,提问作者Trick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 04:35:37