考慮在當前 FPGA 架構上創建一個支持 100 萬到 1600 萬個點的頻域濾波器,采樣率從每秒 1.2 億到 2.4 億個樣本。該示例著眼于使用 OpenCL 的 200 萬點單精度頻域濾波器的設計決策選項。
這種濾波器使用數百萬點一維 (1D) FFT 將其輸入轉換為頻域,將每個頻率和相位分量乘以一個單獨的用戶提供的值,然后將結果轉換回時域快速傅里葉變換。整個系統的總體目標性能要求是每秒 1.5 億個樣本 (MSPS),在具有兩個 DDR3 外部存儲器組的當前一代 FPGA 上實現 200 萬點的樣本大小。輸入和輸出通過 10 Gb 以太網 (GbE) 直接進入 FPGA。
該設計使用面向具有 Stratix V GSD8 FPGA 的 BittWare S5-PCIe-HQ 板的 Altera SDK for OpenCL FPGA 編譯器。使用 OpenCL 而不是低級語言有兩個原因:
第一個原因是設計數百萬點濾波器需要構建復雜但高效的外部存儲系統。使用較低級別的設計工具,創建單個塊,例如片上 FFT 或拐角轉角相對容易(特別是因為每個 FPGA 供應商都已經提供了包含此類塊的庫)。然而,創建外部存儲器系統通常需要大量的 HDL 工作。正如我們稍后會看到的,這種情況可能特別具有挑戰性,因為整個系統的配置在一開始是未知的。
選擇 OpenCL 的第二個原因是對 FPGA 邏輯的主機級控制。對于這個設計,從一開始就很明顯,兩個完整副本的數百萬點 FFT 內核無法容納在單個設備上,因此單個數據集必須至少通過 FPGA 邏輯兩次才能產生最終輸出。協調這種共享,同時允許動態改變數據集大小、乘法系數,甚至完全改變 FPGA 功能以實現其他功能,最好留給 CPU。
使用面向 FPGA 的 OpenCL 編譯器解決了這兩個挑戰,因為它構建了一個定制的高效外部存儲器系統,同時允許對 FPGA 邏輯進行細粒度控制。
片上 FFT
對于這個設計,假設我們已經有一個 FFT 內核,可以處理完全適合 FPGA 的數據大小(稱為“片上 FFT”),因為每個 FPGA 供應商都提供這樣的內核。這樣的核心至少可以通過以下方式參數化:
數據類型(固定或單精度浮點)
要處理的點數 (N)
并行處理的點數 (POINTS)
動態支持更改要處理的點數
給定這樣一個片上 FFT 核,構建整個系統需要兩個步驟:首先,構建一個可以處理數百萬點的 FFT 核,其次,將兩個這樣的核拼接在一起,并在它們之間進行復雜的乘法運算以創建整個系統。
數百萬點 FFT
使用外部存儲實現 FFT 的經典方法是圖 1 所示的六步算法,該算法將單個一維數據集視為二維 (2M = 2K x 1K)[1]。
圖 1:六步 FFT 算法的邏輯視圖。
六步算法顯示了單獨的計算內核和外部內存緩沖區。“Fetch”內核從外部存儲器讀取數據,可選擇轉置,并將其輸出到通道(在 OpenCL 2.0 命名法中也稱為“管道”)。在硬件中,通道被實現為具有編譯器計算深度的 FIFO。“片上 1D FFT”是未經修改的供應商的 FFT 內核,使用通道獲取輸入并產生位反轉輸出。“轉置”總是轉置從其輸入通道讀取的數據,可選擇將其乘以特殊的旋轉因子,并以自然順序將輸出寫入外部存儲器。
如圖所示,數據通過 Fetch ? 1D FFT ? Transpose (F1T) 管道發送兩次以產生最終輸出。這為我們提供了第一個重要的設計選擇:要么擁有一個 F1T 管道副本以節省空間,要么擁有兩個副本以獲得更高的吞吐量。
該算法的初始原型設計是在模擬器中完成的,以確保轉置和旋轉因子的地址操作是正確的。仿真器將 OpenCL 內核編譯為 x86-64 二進制代碼,可以在沒有 FPGA 的開發機器上運行。從模擬器到硬件編譯是一個輕松的步驟,因為模擬器中功能正確的代碼變成了硬件中功能正確的代碼,因此不需要模擬。
出于性能和面積原因,唯一需要修改的是 Fetch 和 Transpose 內核使用的本地內存系統。高效的轉置需要緩沖POINTS本地內存中的列/行數據。OpenCL 編譯器分析 OpenCL 代碼中對本地存儲器的所有訪問,并創建針對該代碼優化的自定義片上存儲器系統。在 POINTS=4 的情況下,原始轉置內核有四次寫入和四次讀取。一個雙泵的片上 RAM 塊最多可以服務四個單獨的請求,其中最多兩個是寫入。為了支持四寫四讀,片上存儲器需要同時復制并包含請求仲裁邏輯,這會導致區域膨脹和性能損失。但是,可以更改寫入模式以使所有四個寫入連續。OpenCL 編譯器將這四次寫入分組為一次寬寫入,只提供對本地內存系統的五次訪問:一次寫入和四次讀取。有了這樣的改變,
將設計編譯到硬件后,就可以測量性能了。使用 FPGA 上的 F1T 流水線的單個副本,我們測量了 217 MSPS,POINTS=4 和 457 MSPS,POINTS=8,對于 400 萬-點 FFT[2]。POINTS=8 版本使用了兩倍的片上 Block RAM,并且此配置中的兩個副本不適合。這為我們提供了第一個要探索的設計維度——并行處理的點數與面積。
全過濾設計
現在我們有了數百萬點的 FFT,我們準備將整個設計放在一起。只需拼接兩個片外 FFT,我們就可以得到圖 2 中整個流水線的邏輯視圖。
圖 2:為簡潔起見,完整過濾器系統的此邏輯視圖顯示 F1T 管道表示為單個塊。
除了復制單個片外 FFT 計算流水線外,系統還添加了以下部分:
頻域中的復數乘法被吸收到第三個 F1T 塊中。coef緩沖區保存著兩百萬個復數乘法系數。
添加了 I/O 輸入和 I/O 輸出內核,以真實地模擬外部存儲器上 10 GbE 通道的額外負載。使用這些內核,我們可以繼續純粹基于軟件的開發,并在核心計算管道完全優化之前離開以太網通道集成。內核中的 I/O 每個時鐘周期生成一個樣本,而 I/O 輸出每個時鐘周期消耗一個樣本。
正如片外 FFT 的實驗所示,我們只能擬合兩個 F1T 塊,并且只能使用 POINTS=4。因此,數據必須通過硬件兩次才能進行完整計算。這使我們的 200 萬個點的整體系統吞吐量僅為 120 MSPS,低于我們 150 MSPS 的目標。但是,通過將數據大小減少到 100 萬個點,我們能夠擬合 POINTS=8 的版本并獲得 198 MSPS 的吞吐量。這表明,只要我們能制作一個適合 200 萬個點的 POINTS=8 版本,性能還是有的。
選擇圖 2 中完整流水線的優化結構是整個設計過程的下一步。我們可以做的第一個改進是刪除tmp3緩沖區。雙方以相同的方式訪問它(轉置寫入和讀取),因此第二個和第三個 F1T 塊可以通過通道直接連接。這需要讓 Transpose 內核將其輸出寫入外部存儲器或寫入通道,并對 Fetch 進行類似的更改。這種變化是由主機動態控制的,因此可以使用單個物理 Fetch 實例。請注意,這會改變我們與外部存儲器的連接,但我們完全不必擔心這一點,因為 OpenCL 編譯器總是為我們的系統生成高效的自定義外部存儲器互連。
進一步的改進是將第二個轉置“T”從寫入tmp1移動到從tmp1讀取(tmp1中的數據存儲方式不同,但最終效果相同)。這消除了對轉置使用的一個本地內存緩沖區的需要。盡管這種改變并不難實施,但我們決定放棄它以代替更激進的想法。
我們最初的轉置實現分兩個階段完成:
首先將所有需要的數據加載到本地內存中,然后使用轉置地址從本地內存中讀取。為了有效利用這樣的管道,OpenCL 編譯器會自動對本地內存系統進行雙緩沖。這樣,管道的加載部分可以將數據加載到一個副本中,而讀取部分可以從另一個副本中讀取先前的數據集。
這種自動雙緩沖對我們的轉置算法來說是正確的,但它很昂貴。相反,我們將轉置內核重寫為就地。這樣的內核只需要一個緩沖區,并且支持同時讀取和寫入多個數據點(但是關于這個轉置內核我們將在另一時間詳細描述)。
通過這些更改,我們能夠在 POINTS=8 配置中安裝 200 萬點 FFT,并實現 164 MSPS 吞吐量。
調度
只有兩個 F1T 副本可以容納,但圖 3 顯示了如何安排數據流以充分利用管道。請注意,在穩定狀態下,管道會在一次處理兩個和三個數據集之間交替,而無需額外的緩沖區。此調度由在 CPU 上運行的主機程序控制,并使用 Dynamic Profiler 工具進行驗證。
圖 3:在內核調度方面,“0”是 F1T 管道的第一個物理副本,“1”是第二個副本。紫色箭頭通過管道跟隨單個數據集。
緩沖區分配
在 OpenCL 系統中,主機程序控制哪個 DDR bank 包含哪些緩沖區。由于 DDR bank 在讀取或寫入時效率最高,但不是兩者兼而有之,因此我們可以將五個緩沖區拆分為兩個 DDR bank,如下所示:
DDR bank #0 獲得輸入和tmp2
DDR bank #1 獲取tmp1、coef和out
將緩沖區分配給 DDR bank 是 OpenCL 主機程序中的一行更改。編譯器和底層平臺負責其余的工作。鑒于這種自動化,我們可以在 2-DDR 和 4-DDR 板上進行試驗,以找到每個板的緩沖區到 bank 的最佳映射。
結論
本文介紹如何使用 Altera OpenCL SDK for FPGA 設計 200 萬點頻域濾波器。所有功能驗證均使用軟件樣式的仿真完成,并且每個硬件編譯都能正常工作。我們沒有打開硬件模擬器,也從不擔心時序收斂。
作者:Dmitry Denisenko,Mykhailo Popryaga
審核編輯:郭婷
-
濾波器
+關注
關注
161文章
7799瀏覽量
178010 -
DDR
+關注
關注
11文章
712瀏覽量
65318 -
模擬器
+關注
關注
2文章
875瀏覽量
43210
發布評論請先 登錄
相關推薦
評論