據(jù)觀察,HLS的發(fā)展呈現(xiàn)愈演愈烈的趨勢(shì),隨著Xilinx Vivado HLS的推出,intel也快馬加鞭的推出了其HLS工具。HLS可以在一定程度上降低FPGA的入門門檻(不用編寫(xiě)RTL代碼),也可以在某些場(chǎng)合加速設(shè)計(jì)與驗(yàn)證(例如在FPGA上實(shí)現(xiàn)OpenCV函數(shù)),但個(gè)人還是喜歡直接從RTL入手,這樣可以更好的把握硬件結(jié)構(gòu)。Xilinx官方文檔表示利用HLS進(jìn)行設(shè)計(jì)可以大大加速設(shè)計(jì)進(jìn)度:
XIlinx官方文檔片段
所以為了緊隨時(shí)代潮流,所以也抽空玩了一下Xilinx的HLS工具,下面把整個(gè)過(guò)程分享給大家。我這里選擇Cordic算法作為我的實(shí)現(xiàn)目標(biāo)。Cordic算法原理很簡(jiǎn)單,所以這里不再贅述。首先介紹一下Vivado HLS設(shè)計(jì)流程:
Vivado HLS設(shè)計(jì)流程
可以看出我們需要做的是完成C/C++設(shè)計(jì)、Testbench編寫(xiě)以及Constraints/directives的添加。其中Constraints/directives是指利用約束/指令使HLS綜合出的RTL代碼更符合要求。接著,我們就可以利用HLS進(jìn)行C層仿真與驗(yàn)證、C/RTL混合仿真與驗(yàn)證以及RTL代碼的生成與打包。綜上,HLS設(shè)計(jì)的主要工作內(nèi)容包括三點(diǎn):C/C++設(shè)計(jì)、Testbench設(shè)計(jì)以及約束的添加。下面就從這三點(diǎn)開(kāi)始介紹。
一. Cordic算法的C++實(shí)現(xiàn)
算法頭文件Cordic.h代碼如下:
#include
頭文件的重點(diǎn)是聲明數(shù)據(jù)類型。這里采用HLS中特有的定點(diǎn)數(shù)形式,包含ap_fixed.h與ap_int.h即可。由于輸入為有符號(hào)弧度制(-3.1415~+3.1415),輸出為-1~+1,所以定義兩種數(shù)據(jù)精度:
di_t :17bits = 1bit符號(hào)位 + 2bit整數(shù) + 14bit小數(shù)
do_t:16bits = 1bit符號(hào)位 + 1bit整數(shù) + 14bit小數(shù)
接著聲明了函數(shù)與兩個(gè)算法所需參數(shù)。
算法文件Cordic.cpp代碼如下(注意:由于使用C++頭文件ap_fixed.h,所以必須采用.cpp文件,否則編譯出錯(cuò)):
#include"Cordic.h"void pre_cir_cordic(di_t full_alpha, di_t &alpha, flag_t &flag){ if(full_alpha > PI/2) { alpha = PI - full_alpha; flag = 2; } else if(full_alpha < -PI/2) { alpha = -PI - full_alpha; flag = 3; } else { alpha = full_alpha; flag = 0; }}void cir_cordic_calculate(di_t alpha, flag_t flag, do_t &mysin, do_t &mycos, flag_t &flag_delay){ const int N = 15; do_t xi[N]; do_t yi[N]; di_t zi[N]; flag_t flag_delay_a[N]; xi[0] = Kn; yi[0] = 0; zi[0] = alpha; flag_delay_a[0] = flag; const di_t myarctan[15] = { 0.7853981, 0.4636476, 0.2449787, 0.1243549, 0.0624188, 0.0312398, 0.0156237, 0.0078123, 0.0039062, 0.0019531, 0.0009765, 0.0004883, 0.0002441, 0.0001221, 0.0000610 }; int m = 0; for(m = 0; m
算法主要有三個(gè)函數(shù)組成:
1.pre_cir_cordic:將輸入角度從-π~+π映射到 -π/2~+π/2中。
2.cir_cordic_calculate:利用旋轉(zhuǎn)公式進(jìn)行Cordic算法計(jì)算,這里設(shè)置旋轉(zhuǎn)次數(shù)為15次,精度較高。
3.post_cir_cordic:根據(jù)輸入角度矯正輸出值正負(fù)。
最后,通過(guò)cir_cordic函數(shù)實(shí)現(xiàn)上述三個(gè)函數(shù)的整合。至此,Cordic算法的C++設(shè)計(jì)結(jié)束。
二. Testbench設(shè)計(jì)
為了驗(yàn)證設(shè)計(jì)的正確性,需要編寫(xiě)Testbench對(duì)C++代碼以及綜合后的RTL進(jìn)行測(cè)試。本文的Testbench.cpp代碼如下:
#include "Cordic.h"#include
本測(cè)試平臺(tái)利用隨機(jī)數(shù)生成-π~+π的測(cè)試向量對(duì)程序進(jìn)行測(cè)試。以math.h中的三角函數(shù)作為評(píng)判標(biāo)準(zhǔn)。為了縮短時(shí)間,選擇100組測(cè)試向量進(jìn)行測(cè)試,若算法誤差大于給定值,則報(bào)錯(cuò);若算法誤差均小于給定值,則輸出驗(yàn)證通過(guò)信息。C驗(yàn)證平臺(tái)設(shè)計(jì)完成。
三. 驗(yàn)證與directives的添加
1.初步算法的C仿真與綜合
根據(jù)上述代碼,可以對(duì)工程進(jìn)行C仿真,仿真結(jié)果如下:
C仿真結(jié)果
可以看出C仿真通過(guò),算法正確。接著綜合工程,得到綜合結(jié)果如下:
C綜合報(bào)告
可以看出代碼時(shí)鐘符合要求,但是Latency(延遲)和Interval(吞吐量倒數(shù))較大。此時(shí)吞吐量較小,64個(gè)時(shí)鐘輸出一個(gè)計(jì)算結(jié)果,并沒(méi)有發(fā)揮FPGA的并行優(yōu)勢(shì),所以需要添加Directives對(duì)工程綜合進(jìn)行約束。
2.Directives添加
由于Cordic算法中旋轉(zhuǎn)公式部分為循環(huán),所以將循環(huán)展開(kāi)并加入流水線可以大大減小延時(shí)以及增加吞吐量。同時(shí)也對(duì)計(jì)算函數(shù)加入流水線以提高吞吐量。建立一個(gè)新的solution:Add_Directives,其Directive添加結(jié)果如下:
Directive添加結(jié)果
此時(shí)再對(duì)算法進(jìn)行綜合,得到綜合報(bào)告對(duì)比如下:
綜合報(bào)告對(duì)比
可以看出添加Directives后,吞吐量大大提高,已經(jīng)達(dá)到最大值,即每個(gè)時(shí)鐘都輸出一個(gè)計(jì)算結(jié)果。算法延時(shí)也從63個(gè)clk減小到4個(gè)clk,此時(shí)RTL代碼已經(jīng)較為理想。
3.C/RTL聯(lián)合仿真
由上,代碼設(shè)計(jì)部分與約束添加已經(jīng)全部完成,下面進(jìn)行聯(lián)合仿真,對(duì)RTL代碼進(jìn)行驗(yàn)證。驗(yàn)證報(bào)告如下:
混合仿真報(bào)告
可以看出RTL仿真與C仿真均通過(guò),說(shuō)明設(shè)計(jì)正確。利用Vivado simulator打開(kāi)RTL仿真波形,如下:
RTL仿真波形
可以看出RTL波形中明顯體現(xiàn)出4 clk的Latency和1 clk的Interval,并且利用計(jì)算器進(jìn)行驗(yàn)算,證明計(jì)算結(jié)果正確,所以RTL代碼綜合成功。
四. IP打包
直接利用HLS進(jìn)行IP打包即可生成IP核。在相應(yīng)工程中引入IP核路徑(在對(duì)應(yīng)solution內(nèi)的impl文件夾內(nèi))即可調(diào)用HLS生成的IP核。本IP核接口如下:
Cordic IP
那么根據(jù)上節(jié)仿真波形進(jìn)行接口輸入的描述就可以使用該IP。至此,整個(gè)HLS設(shè)計(jì)過(guò)程結(jié)束。
五. 總結(jié)
整個(gè)HLS設(shè)計(jì)過(guò)程還是比較清晰的,重點(diǎn)在于了解HLS的支持范圍以編寫(xiě)符合規(guī)范的高層次代碼,其次是對(duì)硬件有一定認(rèn)識(shí)以引入合適的directives。HLS的確在很大程度上加快了設(shè)計(jì)進(jìn)度,使用也非常方便,所以我以后決定還是從RTL層面進(jìn)行設(shè)計(jì),因?yàn)槟菢佑X(jué)得自己更NB一點(diǎn)。
-
RTL
+關(guān)注
關(guān)注
1文章
385瀏覽量
59937 -
HLS
+關(guān)注
關(guān)注
1文章
130瀏覽量
24197
原文標(biāo)題:利用Xilinx HLS將C++代碼快速部署于FPGA(Cordic算法)
文章出處:【微信號(hào):zhuyandz,微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論