如何將C / C++ / OpenCL編譯成硬件加速器
介紹
在這里,我們提供了一個關(guān)于如何生成靜態(tài)比特流的分步教程。我們以Sobel邊緣檢測算法為例來演示這一過程。但是,對于您可能想要創(chuàng)建的其他模塊,步驟是相同的。
設(shè)置
下面列出了我用來生成Sobel算法的靜態(tài)比特流的工具:
工具使用:
?Vivado 2018.3
?Ubuntu 16.04.5 LTS
?Avnet Ultra96v1開發(fā)板
?OpenCL, OpenCV, C/ c++
?Sobel OpenCL代碼
使用Vivado HLS創(chuàng)建自定義模塊
步驟1 -創(chuàng)建一個新項目
?要創(chuàng)建一個新項目,請轉(zhuǎn)到File > new project
?為項目選擇合適的名稱和位置。
?接下來,輸入程序中主函數(shù)的名稱。在我們的例子中,這是krnl_sobel。從這里您可以導(dǎo)入源文件。您還可以在稍后的過程中導(dǎo)入源文件,我將指出這一點。
?這同樣適用于測試臺架文件。
?該屏幕允許我們將模塊定制為特定的體系結(jié)構(gòu)。單擊下一個窗口的“部件選擇”區(qū)域中的3個點。從這個窗口,您可以選擇一個特定的FPGA或板。在本教程中,我們選擇一個特定的板來合成我們的模塊。需要注意的是,Vivado 2018.3不包含Ultra96平臺的入口。然而,在設(shè)計模塊時,我們發(fā)現(xiàn)使用ZCU102平臺可以很好地工作,因為它們都使用相同的ZYNQ FPGA。
?我們不需要擔(dān)心窗口時鐘部分的任何選項。您可以為您的解決方案選擇一個不同的名稱。
?最后要做的事情是選擇Finish按鈕。
?從這里右鍵單擊資源管理器菜單中的源文件,然后選擇新建文件…從這里導(dǎo)航到包含要導(dǎo)入的源文件的目錄。在同一個資源管理器菜單中的“測試臺”也是如此。應(yīng)該注意的是,您應(yīng)該包含模塊需要測試的任何頭文件或測試數(shù)據(jù)。
?您可以通過從source目錄打開該文件來查看和修改源代碼。對于本教程,源代碼將在不修改的情況下自動合成。“雜項”部分包含我們對源代碼所做的修改,這樣它就可以與更大的項目兼容。
步驟2 - C仿真
步驟3 -合成和創(chuàng)建RTL模塊
?開始合成的按鈕是綠色三角形。
?如果合成成功,將出現(xiàn)以下選項卡:
?此頁簽包含生成的接口信息。例如,從和主AXI端口的總線寬度
?要創(chuàng)建在Vivado方框圖中使用的RTL模塊,只需按下“Export RTL”按鈕。
?對于本教程,您可以將這些選項保留為默認(rèn)值。
在Vivado中使用自定義模塊
步驟1 -創(chuàng)建一個新項目
?要創(chuàng)建一個新項目,請轉(zhuǎn)到File > project > new…
?按下next鍵進入以下屏幕:
?在繼續(xù)之前,為新項目選擇一個合適的名稱和位置
?對于本教程,在下一個菜單中選擇RTL項目選項
?下一個窗口是將源文件添加到塊設(shè)計的一種方法:
?在本教程中,我們使用不同的方法。然而,兩者是相等的
?在本教程中,我們不會添加任何約束
?對于默認(rèn)的部件菜單,我們將轉(zhuǎn)到電路板并選擇Ultra96v1評估平臺
?如果一切正常,您可以單擊Finish按鈕并開始使用框圖
?在下一個窗口中,您可以添加sobel模塊。去工具>設(shè)置…> IP >存儲庫
?從這里,轉(zhuǎn)到Add,然后導(dǎo)航到存儲sobel模塊的位置。注意,只需要選擇文件夾,Vivado會自動檢測其中的IP。完成后,單擊Apply和OK
步驟2 -創(chuàng)建塊設(shè)計
?從Vivado窗口的Flow Navigator菜單中,您可以選擇Create Block Design選項開始
?除了設(shè)計名稱外,所有內(nèi)容保持不變,設(shè)計名稱可以根據(jù)您的判斷進行更改。
?在Vivado窗口的Diagram部分,您可以單擊,或者按CTRL + I,向圖中添加新的IP
?首先獲得代表您的處理系統(tǒng)的塊,PS.對于本教程,我們使用Zynq Ultrascale+ MPSoC PS.然后單擊彈出的“運行塊自動化”鏈接。確保選中PS并單擊OK
?接下來我們要設(shè)置的是一個從和主AXI端口,用于將PS連接到我們創(chuàng)建的Sobel模塊。要做到這一點,雙擊PS塊。進入“PS-PL Configuration > PS-PL Interfaces > Master Interface”,選擇其中一個選項。然后轉(zhuǎn)到Slave Interface > AXI HP并選擇其中一個選項
?現(xiàn)在我們添加我們創(chuàng)建的Sobel模塊。為此,導(dǎo)航到菜單,通常選擇您想要的IP并搜索您在Vivado HLS中指定的頂級函數(shù)的名稱。在我們的例子中,這是Krnl_sobel。將其添加到塊設(shè)計中。
?在彈出的窗口中單擊“Run Connection Automation”鏈接。這將添加必要的連接塊,我們需要能夠使用Sobel模塊。在按OK之前,確保所有的框都被選中了。
步驟3 -生成比特流
?生成比特流是一項簡單的任務(wù),但首先,我們需要驗證我們的設(shè)計。從Diagram窗口的頂部選擇Validate Design選項,或者按F6。如果這樣做正確,它應(yīng)該告訴您從AXI端口被排除。
?這可以通過地址編輯器選項卡和打開sobel模塊部分,然后排除地址段來修復(fù)。要修復(fù)驗證問題,只需右鍵單擊被排除的地址段并選擇Include segment。
重新驗證設(shè)計
?在生成比特流之前,我們需要為我們的設(shè)計創(chuàng)建一個HDL包裝器。這很容易做到。轉(zhuǎn)到Vivado屏幕上的源菜單,右鍵單擊要創(chuàng)建包裝器的設(shè)計文件,然后選擇“創(chuàng)建HDL包裝器”。保持所有為默認(rèn)值并選擇OK。
?從Flow Navigator菜單中選擇Generate Bitstream。保持所有內(nèi)容為默認(rèn)值并單擊OK。這一步需要一些時間,所以去拿一杯飲料然后回來。
?要查找比特流,請導(dǎo)航到為項目創(chuàng)建的目錄。對于我們來說,我們將導(dǎo)航到sobel.runs/impl_1/design_1_wrapper.bit。注意,sobel是我們目錄的名稱,它將被您命名的目錄所替換。
?一旦你找到了。我們需要轉(zhuǎn)換可以加載到FPGA上的圖像文件。為此,我們使用Xilinx的Bootgen。這很容易做到。最好在您找到的目錄中。比特文件,創(chuàng)建一個名為bitstream.bif的文件。其內(nèi)容應(yīng)如下:
一旦比特流。如果文件已創(chuàng)建,只需執(zhí)行以下命令:
Misc
本節(jié)包含在開發(fā)過程中可能需要或想要的有用修改
32位和64位接口
采用原始的Sobel OpenCL代碼,數(shù)據(jù)總線為512位。對我們來說,這仍然是可用的,但它可以改變。為此,根據(jù)變量的不同,我們修改了函數(shù)形參列表,使其傳遞整型和整型指針。然后,我們將輸入?yún)?shù)轉(zhuǎn)換為原始類型的新變量。這使我們能夠控制數(shù)據(jù)總線的寬度。
為了使用64位數(shù)據(jù)總線,您只需要在合成前向HLS中的配置添加一個選項。在Vivado HLS中,單擊兩個稱為解決方案設(shè)置的黃色齒輪…,單擊“添加”,在“命令”下拉菜單中選擇“config_interface”。確保選中m_axi_addr64選項。
現(xiàn)在在合成之后,您的數(shù)據(jù)總線應(yīng)該是64位寬
注:請記住,如果您創(chuàng)建64位接口,模塊內(nèi)部寄存器將是64位。您需要將這些上32位設(shè)置為0,否則,模塊將使用存儲在上32位中的任何值,并導(dǎo)致潛在的任意行為。
HLS中的主、從軸Pragma
掌握語法
如果你發(fā)現(xiàn)你需要映射一個參數(shù)到內(nèi)存端口,基本結(jié)構(gòu)如下:
Variable_name是一個表示數(shù)組的變量。應(yīng)該注意的是,您應(yīng)該只將數(shù)組映射到內(nèi)存端口
本文編譯自hackster.io