白皮書

使用網路示例比較 FPGA RTL 與 HLS C/C++

概述

大多數FPGA程式師認為,高級工具總是發出更大的比特流作為提高生產率的“成本”。但這總是正確的嗎?在本文中,我們展示了一個真實的例子,其中我們創建了一個通用的網路函數RSS,使用傳統的RTL / Verilog工具,然後在同一硬體上使用高級合成(HLS)。我們的發現令人驚訝:HLS方法實際上使用了更少的FPGA門和記憶體。這是有原因的。請繼續閱讀以瞭解詳細資訊。

FPGA開發的HLS方法只是抽象出可以在C/C++環境中輕鬆表達的應用部分。HLS 工具流基本上可用於任何 BittWare 板卡,通過使用 Vivado (Xilinx) 或 Intel (Quartus) 工具。

若要成功使用 HLS,請務必識別應用程式中適合的部分。指南包括:

  • 目標用途通常是以高級語言定義的IP塊。數學演算法可以很好地工作,或者像我們的RSS塊一樣,可以進行一些網路協議處理。
  • 另一類用途是定義不明確的塊,因此可能需要多輪實現。這裡最大的好處是允許HLS工具自動流水線生成的原生FPGA代碼,通常發出的階段比快速手動編碼流水線要少。此外,當需要修改手動編碼的管道時,一個並行路徑上的延遲更改可能會對所有內容產生連鎖反應。使用HLS工具從頭開始第二次自動管道化,消除了這種麻煩。
  • 最後,HLS流程可以更輕鬆地在FPGA品牌和速度等級之間移植代碼。這是因為 HLS 會自動生成適當數量的管道階段,這是您在使用 Verilog 或 VHDL 時需要手動指定的。

HLS目前的局限性顯然是其範圍僅限於IP塊。應用程式團隊仍然需要RTL用於其他元件,儘管利用BittWare的SmartNIC Shell之類的東西作為RTL部件,使用者可能能夠完全在HLS中定義其獨特的應用程式。還應該注意的是,對於最簡單的代碼或主要由預優化元件組成的大型設計,HLS是一個糟糕的選擇。

我們的應用:在 FPGA 上聯網 RSS

什麼是 RSS?RSS代表「接收器端縮放」。。它是一種哈希演算法,用於在多個 CPU 之間有效地分發網路數據包。RSS是現代乙太網卡上的一項功能,通常實現Microsoft定義的特定Toeplitz哈希。

託管我們的RSS應用程式的環境是BittWare的SmartNIC Shell。SmartNIC Shell 旨在讓用戶在構建基於 FPGA 的網路應用時搶佔先機。它為使用者提供了優化的基於FPGA的100G乙太網管道,包括用於主機交互的DPDK。使用者需要做的就是將其應用程式作為IP塊放置。

在這種情況下,BittWare也是使用者,它創建了RSS的FPGA實現作為我們的應用程式。使用傳統 RTL 方法創建 RSS 的團隊和 HLS 團隊都能夠使用 SmartNIC Shell 作為其 FPGA 乙太網框架,並專注於 RSS 應用程式本身。

BittWare的RSS實現

我們基於 FPGA 的 RSS 實現專門基於 DPDK 原始程式碼樹中的 C 代碼,該代碼的測試功能也可在樹中使用。我們的 RSS 應用程式還使用 64 個條目的間接尋址表,而不是更常見的 128 個條目表。對於這項HLS研究來說,重要的是,我們進入FPGA的函數從C開始定義。這符合我們對HLS成功的首要標準 - C或C++的定義。

使用元組對數據包進行分組

RSS 函數的目標是在 CPU 之間分發數據包,從而將相關的數據包流保持在一起。不同的 Toeplitz 金鑰集提供不同的分發模式。但是,無論金鑰集如何,我們的 RSS 函數都使用每個數據包的源和目標 IP 位址以及源和目標埠作為輸入。這四個元件組合在一起稱為 4 元組。

請注意,對於我們的 RSS 應用程式,我們假設 4 元組已經過解析並添加到數據包的元數據中。另一個 SmartNIC 外殼模組處理此數據包分類功能。我們將該模組稱為“解析器”,並將作為單獨的 BittWare 白皮書的主題。

我們的 RSS 實現目前接受 96 位字段進行分類,這足以滿足 IPv4 源 / 目標和埠的 4 元組的需求。解析器為數據包中不可用的欄位提供零。如果數據包不包含任何IP有效負載,則完整的96位元組字段為零。

許多 RSS 實現使用 5 元組而不是 4 元組。這樣做需要額外的8位來容納協議號。RSS 的 HLS 使用者可以通過對原始程式碼進行細微的更改來輕鬆適應這種更改。這種從 4 元組快速適應到 5 元組的能力是 HLS 成功的第二大標準示例 - 這是多輪實現的要求。

FPGA 開發 工具 條款

開發要在FPGA內運行的IP傳統上使用最初為ASIC開發而創建的語言。關於如何稱呼這些語言,還沒有達成共識。有時人們使用“RTL”,它代表註冊轉移語言。其他人使用「HDL」,它代表硬體定義語言。兩個最受歡迎的HDL是VHDL和SystemVerilog。在內部,BittWare同時使用兩者,但我們的大型專案使用SystemVerilog,它的完整驗證功能集。

驗證 是 FPGA 設計 過程 的 一個重要 部分, 也是 ASIC 設計 中 的關鍵 部分。ASIC行業成本的上升推動了對高級驗證語言和技術的需求,以確保首次通過晶元的成功。這種需求促使Verilog語言整合了HVLs(高級驗證語言)的功能,最終合併到當前的SystemVerilog IEEE 1800標準中。現代ASIC驗證也已轉向通用驗證方法(UVM),該方法提供了構建測試平台的標準方法。

FPGA開發的不同經濟性以及在實驗室中立即測試設計的能力減緩了FPGA開發人員對UVM的採用。然而,高密度FPGA日益複雜,促使許多團隊採用與ASIC設計流程相同的驗證方法。在BittWare,我們有一種流暢的FPGA驗證方法。我們經常使用基於廉價或免費模擬器中提供的SystemVerilog或VHDL功能的簡單測試平臺。但是,在適當的時候,我們基於SystemVerilog和UVM的完整功能集構建現代測試平臺。

HLS或高級綜合是賦予在比HDL更高的抽象級別上運行的語言的名稱。在實踐中,HLS通常是指C或C++的專用版本。但是,還有其他HLS語言。例如,BittWare分發的一些第三方IP是用BlueSpec編寫的。所有這些HLS工具往往都帶有一種簡單的按鈕方式,可以在模組級別生成測試平臺。在系統級別仍然需要UVM。

最後,在當今的最高水準上,是OpenCL。它是一種為GPU晶元開發的並行程式設計語言,並重新用於FPGA世界。如今,OpenCL的應用程式幾乎完全是HPC或高性能計算,用於實現運行速度比基於英特爾的伺服器運行速度更快的計算演算法。

HLS 性能編碼

儘管使用 HLS 提供了類似軟體的工具流,但開發人員仍必須學習以硬體為中心的概念,例如流水線和反覆運算間隔,這些概念在為傳統處理器編寫 C 代碼時可能尚未接觸。

HLS代碼主要用於開發嵌入式設計的IP元件,通常是流水線的。我們的 RSS 應用程式也不例外。對於 RSS,最低性能要求是每個 512 位輸入字的處理速度足夠快,以跟上飽和的 100 Gb/s 網路介面。這相當於每個時鐘週期以300MHz的頻率處理一個新字。這個頻率具有挑戰性,因為即使是最快的FPGA也能以不高於400MHz的頻率運行。顯然,我們必須在每個時鐘上處理一個新單詞。

這引入了反覆運算間隔 (II) 的概念,該概念是指管道中給定邏輯片段完成所需的時鐘週期數。對於 RSS 模組,我們要求每個時鐘都有一個結果,II 為 1。因此,我們需要瞭解如何編寫避免違反此要求的代碼。

高II的原因包括:

  • 當管道的下一個輸出需要管道中另一個變數的未來結果(例如遞歸)時,會導致迴圈間依賴關係。允許使用簡單的遞歸運算元(如累加器),因為FPGA包含可在單個時鐘週期內完成這些計算的邏輯。但是,更複雜的遞歸將需要更高的II值。
  • RSS 設計要求管道的每個階段在 3.3ns 內完成。HLS工具將在需要時插入註冊,以確保每個階段都滿足此計時要求。但是,如果無法流水線組合邏輯,則並不總是能夠這樣做。例如,深度組合邏輯可以是為多個嵌套循環的計算編製索引。
  • 如果目標時鐘頻率太高,並且FPGA結構路由路徑太長而無法滿足時序要求,則II將增加。這個問題的解決方案是將邏輯分成兩條以時鐘頻率一半運行的路徑。

代碼的主體迴圈訪問創建新哈希的必需輸入元組字數。對於此處的示例,我們使用 3 個字的輸入元組作為 96 位的哈希值。

此代碼實現了 RSS 計算的核心。它與從DPDK源樹中提取的原始數據保持不變。因此,在這個RSS塊的情況下,所有的移植工作都是定義塊的AXI介面,並將編譯指示語句添加到定義中,如II。

如果輸入長度是常數,FPGA 可以完全展開兩個環路以創建完全流水線的代碼。

要將IP元件集成到智慧NIC框架工作中,需要定義介面和控制平面,以及讀取和寫入外部介面的任何邏輯。智慧網卡框架使用 AXI 介面協定在元件之間進行通信。

定義 AXI 介面並添加編譯指示語句會導致代碼行數過多,無法在此處的圖中顯示。完整的原始程式碼檔可從BittWare獲得。

存在位元組序性挑戰,因為 Xilinx 編譯器的常量採用英特爾位元組順序(小位元節序),但網路協定使用網路位元組順序(大位元節序)。這不會影響性能或資源使用,但要求任何輸入數據在 HLS 中處理之前都更改其位元組序。

原生程式設計與HLS:結果

我們有兩個FPGA RSS實現的原因是因為我們的初始版本是用Verilog編寫的。這是在我們正在評估的假設下發生的:本機FPGA編碼始終導致最小的資源使用量。然而,BittWare的一位工程師對這一決定提出了質疑,並在HLS中重新實現了RSS來測試這種方法。他是對的,BittWare現在已經用HLS代碼替換了我們SmartNIC Shell中的RSS模組和解析器模組。

兩種 RSS 實現

特徵VerilogHLS C
斷續器44,4352,385
布拉姆121
寄存 器52,3524,843
代碼行650459

這兩個實現之間最大的區別在於 Verilog/RTL 版本使用 FIFO,而 HLS C++ 版本不使用。我們驚訝地發現,遷移到 HLS 後,資源使用量實際上有所下降,而這在所有情況下都是我們意想不到的。

節省的時間呢?粗略地說,我們看到原生RTL版本的時程表為一個月,而HLS代碼在一周內完成。

英特爾 HLS 與賽靈思 HLS 的對比

本示例使用 Xilinx HLS。然而,使用高級語言的一個關鍵優勢是它們能夠在一定程度上抽象出不同技術架構之間的潛在差異。英特爾還有一個等效的編譯器,該編譯器還可以將C++編譯為門控RTL代碼。

為了使用英特爾 i++ 編譯器編譯相同的代碼,需要對數據類型進行一些細微的更改,並對#pragmas進行更改。英特爾和賽靈思之間最大的區別在於英特爾使用 Avalon 流介面,Xilinx 使用 AXI 流介面。這將需要一個簡單的填充程式介面來從一個介面轉換為另一個介面。

協同模擬

一旦功能得到驗證,調用協同模擬環境進行週期精確的RTL仿真是一項微不足道的任務。Vivado-HLS 自動生成一個 RTL 測試平臺,該測試平臺由原始C++代碼生成的向量驅動。使用者需要的唯一修改是處理其設計中的任何無限迴圈或阻塞介面。RSS 模組設計為作為韌體管道的一部分無限期運行。因此,模擬永遠不會完成,協同類比將掛起。為了避免這種情況,我們將 RSS 代碼的 「while (1)」 主迴圈更改為固定長度,長度足以消耗來自測試平臺的所有輸入,並且足夠長以生成所需的所有輸出。

協同模擬提供了額外的置信度,即RTL是由模組的工具和時序特性正確生成的,符合原始設計參數。

協同模擬流程也可作為英特爾 HLS 工具堆疊的一部分提供。

按IP塊構建 HLS

HLS 工具流需要內置對所用介面協定的感知能力。BittWare的IP塊通常使用高級可擴展介面(AXI)進行通信。具體而言,AXI4-Stream用於傳遞數據包數據,AXI4-Lite作為控制平面。

對於 100 GbE,BittWare 使用 AXI4-Stream 介面,該介面寬 512 位,時鐘頻率為 300 MHz。當斷言數據包數據的 TLAST 信號時,與每個數據包關聯的元數據都遵循其自己的總線,該總線在數據包末尾有效。數據包元數據在塊之間和版本之間演變。它通常包括有關以下內容的資訊:

  • 數據包到達的物理乙太網連接器的編號
  • MAC 識別的與數據包關聯的任何錯誤
  • 80 位 IEEE-1588 格式的時間戳,有時是縮短的 64 位格式的時間戳
  • “已刪除”位,指示下次需要從流中刪除數據包
  • 我們通常稱之為「佇列」的數字,用於指示數據包的目的地。它是由管道中的一個IP塊(甚至可能是這個塊)計算的。

我們針對 RSS 塊的控制平面包括:

  • 啟用/禁用位
  • 20 個用於 Toeplitz 哈希的 16 位金鑰
  • 包含 64 個條目的間接尋址表

SmartNIC Shell 框架的示例實現框圖。此處,RSS 塊被替換為 HLS 實現。

結論

當今的高級 FPGA 開發工具旨在縮短上市時間,減少對硬體工程師的依賴。但是,假設使用這些工具總是會降低應用程式性能(無論是在速度還是晶元資源方面),這種假設都是錯誤的。

我們發現使用HLS為BittWare的SmartNIC Shell開發IP塊將開發時間從大約一個月縮短到一周。我們還發現它實際上使用更少的門來實現。

RSS 模組的原始程式碼可供 XUP-P3R 板擁有者和 SmartNIC Shell 使用者使用。它很好地說明瞭如何在HLS代碼中使用AXI介面。聯繫 BittWare 代表以瞭解更多資訊。

除了原生開發工具外,HLS還可用於所有BittWare FPGA板。我們還提供一系列支援 OpenCL 開發的開發板 — 按兩下此處瞭解更多資訊