首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Vivado HLS 入門指南與常見問題解決

     編輯:關於C語言

Vivado High-Level Synthesis (HLS) 入門實戰

Vivado HLS 讓開發者以 C/C++ 描述硬體行為,自動綜合為 RTL(Verilog/VHDL)並封裝為 IP 核。本文整理初學者常遇問題與解決方案,涵蓋指數函數處理、可綜合構造限制、指針與記憶體模型、遞迴與標準庫限制等核心主題。

指數函數 exp() 無法導出 Pcore 問題

現象:使用 exp(x) 時僅支援導出 Vivado IP,不支援舊版 EDK Pcore 導出。

解決方案:採用查表法(LUT)替代運行時計算。預先在 PC 端(VS/Matlab)計算所需範圍的指數值存入陣列,HLS 中直接索引:


void wxFillExpLut(float *lut, int size) {
    for (int i = 0; i < size; i++) {
        lut[i] = expf(-(float)i / LUTPRECISION);
    }
}

優點:消除複雜浮點運算單元,大幅降低資源佔用與延遲;缺點:需預知輸入範圍,精度受表大小限制。

可綜合 C 構造限制

依據 UG902,可綜合函數必須滿足:

  • 功能完整自包含,無作業系統系統呼叫
  • 資料結構大小固定或有明確邊界
  • 語義明確無歧義

不支援的構造

類別說明替代方案
系統呼叫printf, malloc, time 等用 #ifndef __SYNTHESIS__ 隔離仿真代碼;動態記憶體改為靜態陣列
動態記憶體分配malloc/free/new/delete編譯期固定大小陣列 + 指針指向
遞迴函數硬體無法支援不定深度呼叫堆疊改用迴圈展開或有限狀態機
C++ 動態多型虛函數、動態建立/銷毀物件使用樣板靜態多型或函數指針表
標準模板庫 (STL)內部使用動態記憶體改用定長陣列或 HLS 提供的 hls::stream

指針限制與處理技巧

  • 一般指針轉型:僅支援原生 C 型別間轉型,不支援任意轉型
  • 指針陣列:每個指針必須指向純量或純量陣列,不可指向另一層指針
  • 多重指針:int **pp 需轉換為單層指針 + 索引運算

條件編譯最佳實踐

官方建議使用使用者定義宏(如 NO_SYNTH)而非 __SYNTHESIS__:


#ifdef NO_SYNTH
    // 仿真專用:malloc, printf, 檔案 I/O
    long long *out_accum = malloc(sizeof(long long));
#else
    // 可綜合版本:靜態分配
    long long _out_accum;
    long long *out_accum = &_out_accum;
    int _array_local[64];
    int *array_local = _array_local;
#endif

流程:1) 定義宏並修改代碼 2) 啟用宏跑 C 仿真存結果 3) 關閉宏再跑仿真驗證一致性 4) 關閉宏進行綜合。

實用資源連結

  • UG871 Vivado HLS 教學(含 11 個範例)
  • Xilinx 官方參考設計源碼
  • 13 支專家講解影片(Getting Started 到 OpenCV 整合)
  • XAPP 系列應用筆記:Sobel Filter (XAPP890)、OpenCV 加速 (XAPP1167)、浮點 PID (XAPP1163) 等

總結

掌握 HLS 的關鍵在於理解「硬體導向的 C 風格」:固定大小、無動態分配、無 OS 依賴、善用管線化與資料流優化指令。查表法、條件編譯隔離不可綜合代碼、靜態記憶體模型是避開常見陷阱的三大利器。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved