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

如何在SDaccel/Vivado HLS中测量FPGA子组件运行时延迟?

动态延迟测量与SDS Trace使用指南

针对你在SDaccel/Vivado HLS中遇到的动态延迟测量问题,以及SDS trace编译指示的用法,我分享一些实际项目中用过的有效方法:

一、测量子组件动态延迟的实用方案

由于你的子组件延迟随输入数据变化,Vivado HLS的静态分析无法给出准确值,需要结合硬件级调试和仿真手段:

1. 嵌入硬件计数器直接测量

在每个子组件内部添加寄存器级的计数器,跟踪单条数据从输入有效到输出有效之间的时钟周期数。这种方法能直接反映硬件实际运行时的延迟,步骤如下:

  • 在组件内部定义静态计数器变量(确保综合成硬件寄存器),配合输入/输出有效信号触发计数启停:
void feature_extractor(ap_uint<32> in_data, ap_uint<1> in_valid,
                       ap_uint<64> out_data, ap_uint<1>& out_valid,
                       ap_uint<32>& measured_latency) {
    #pragma HLS pipeline II=1
    static ap_uint<32> latency_cnt = 0;
    static ap_uint<1> count_start = 0;

    // 输入有效时启动计数并重置
    if (in_valid) {
        count_start = 1;
        latency_cnt = 0;
    }

    // 子组件核心逻辑(示例:根据输入数据长度动态处理)
    ap_uint<64> temp_data;
    if (in_data > 1024) {
        // 长数据处理路径,延迟更长
        temp_data = in_data * 2;
        #pragma HLS delay 5
    } else {
        // 短数据处理路径
        temp_data = in_data;
        #pragma HLS delay 2
    }

    // 输出有效时锁存延迟值并停止计数
    out_data = temp_data;
    out_valid = (count_start && (latency_cnt >= (in_data>1024 ? 5 : 2)));
    if (out_valid) {
        measured_latency = latency_cnt;
        count_start = 0;
    }

    // 仅在计数阶段累加
    if (count_start) {
        latency_cnt++;
    }
}
  • 将measured_latency通过AXI-Lite接口暴露到PS端,或者连接到ILA调试端口,运行时读取不同输入下的延迟值。

2. 使用Vivado ILA在线抓取波形

通过ILA(Integrated Logic Analyzer)实时监控子组件的关键信号,直观分析动态延迟:

  1. 在HLS导出IP时,勾选"Enable Debug"选项,保留输入有效、输出有效等关键信号的调试端口;
  2. 在Vivado工程中添加ILA核,将子组件的in_valid、out_valid、measured_latency等信号连接到ILA;
  3. 生成比特流并下载到FPGA,运行不同输入数据,触发ILA抓取波形,直接查看每条数据对应的延迟周期。

3. 仿真阶段跟踪时间戳

在C/RTL仿真中,为每条测试数据添加时间戳,对比输入输出的时间差得到延迟:

// 仿真测试代码示例
int main() {
    hls::stream<ap_uint<32>> in_stream;
    hls::stream<ap_uint<64>> out_stream;
    ap_uint<32> in_data;
    ap_uint<64> out_data;
    std::unordered_map<int, int> data_timestamps;
    int cycle = 0;
    int data_idx = 0;

    // 输入测试数据并记录时间戳
    while (data_idx < 100) {
        in_data = (data_idx % 2) ? 2048 : 512; // 交替长/短数据
        in_stream.write(in_data);
        data_timestamps[data_idx] = cycle;
        data_idx++;

        // 读取输出并计算延迟
        if (!out_stream.empty()) {
            out_data = out_stream.read();
            int idx = (out_data > 1024) ? data_idx-1 : data_idx-2; // 根据输出反推索引
            int latency = cycle - data_timestamps[idx];
            std::cout << "Data " << idx << " latency: " << latency << " cycles\n";
        }
        cycle++; // 模拟时钟周期推进
    }
    return 0;
}

这种方法适合前期快速验证延迟趋势,和硬件实测结果可互相印证。

二、#pragma SDS trace详细使用指南

#pragma SDS trace是SDaccel环境中用于跟踪函数性能、数据传输的核心编译指示,能帮你量化子组件的延迟、吞吐量等指标,尤其是动态变化的性能数据:

1. 基本语法与常用选项

  • 全局启用trace:#pragma SDS trace <option>
  • 针对特定函数启用:#pragma SDS trace function(<func_name>) <option>

常用选项:

  • latency:跟踪函数从输入有效到输出有效之间的时钟周期数,记录每条数据的延迟值;
  • throughput:计算函数的吞吐量(单位时间处理的数据量);
  • data:跟踪DDR与PL之间的数据传输延迟、带宽;
  • all:启用所有trace指标。

2. 使用步骤

(1)在代码中添加编译指示

给需要跟踪的子组件函数添加trace指令:

#pragma SDS trace function(feature_extractor) latency throughput
void feature_extractor(...) {
    // 函数逻辑
}

(2)编译时启用trace功能

在SDaccel编译命令中添加--trace选项,或者在Vivado HLS GUI的"Project Settings"中开启"Enable SDS Trace":

sdaccel -c --target hw --trace --output_dir build my_project.cpp

(3)分析trace结果

编译并运行后,会生成trace.dat文件,使用SDaccel自带的sds_trace_report工具生成可视化报告:

sds_trace_report trace.dat -o latency_report.html

报告中会展示每个函数的延迟分布(最小/最大/平均延迟)、吞吐量,以及每条数据的具体延迟值,完美适配你的动态延迟分析需求。

3. 注意事项

  • trace功能会增加硬件资源开销(额外的寄存器和存储),仅用于调试阶段,量产时务必移除相关编译指示;
  • 若要跟踪多个子组件,需为每个函数单独添加#pragma SDS trace;
  • 结合硬件计数器的实测结果与SDS trace的报告,可确保性能数据的准确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:30:32