陳書(shū)祺,占薇,劉益巧,徐龍潔,陳鑫
(南京航空航天大學(xué)電子信息工程學(xué)院,江蘇 南京 211106)
高層次綜合工具大部分都采用C/C++作為輸入并輸出寄存器傳輸級(jí)代碼,從而極大地降低了硬件編程門檻并縮短了開(kāi)發(fā)時(shí)間,HLS 系統(tǒng)還提供了各種優(yōu)化方法使得開(kāi)發(fā)人員可以從高級(jí)語(yǔ)言層面對(duì)硬件結(jié)構(gòu)進(jìn)行優(yōu)化,部分還提供了視圖以方便對(duì)每個(gè)時(shí)鐘周期的電路行為進(jìn)行分析,進(jìn)一步提高了生成RTL 的性能[1]。
文獻(xiàn)[2]顯示,現(xiàn)階段高層次綜合工具已經(jīng)可以應(yīng)用于中、高復(fù)雜度的應(yīng)用系統(tǒng),并且相較于傳統(tǒng)基于寄存器傳輸級(jí)(RTL)的技術(shù)路線,開(kāi)發(fā)周期減少約60%,且最高工作速度提升了一倍。但是,現(xiàn)階段大部分已報(bào)道的高層次綜合工具主要是賽靈思公司開(kāi)發(fā)的Vivado HLS 開(kāi)發(fā)工具[3-4]。由于賽靈思公司是老牌的FPGA 芯片制造商,且Vivado HLS 開(kāi)發(fā)工具源于FPGA 的設(shè)計(jì)工具EDA,因此Vivado HLS 開(kāi)發(fā)工具主要被硬件開(kāi)發(fā)工程師所熟悉。
因?yàn)镸ATLAB 具有運(yùn)算能力強(qiáng)、語(yǔ)法簡(jiǎn)單易于學(xué)習(xí)掌握、應(yīng)用范圍廣等特點(diǎn),廣泛被算法開(kāi)發(fā)工程師所應(yīng)用。雖然MATLAB 也具有高層次綜合工具功能,但經(jīng)檢索發(fā)現(xiàn),國(guó)內(nèi)幾乎沒(méi)有報(bào)道使用MATLAB 作為高層次綜合工具,僅有少部分人嘗試Simulink 結(jié)合HDL Coder 來(lái)完成FPGA 的快速設(shè)計(jì)[5-6]。國(guó)外雖然存在使用HDL Coder 來(lái)轉(zhuǎn)化代碼的個(gè)別案例,但此方法并未被大量采用[7]。此外,所有已發(fā)表文獻(xiàn)僅僅將MATLAB 作為工程的一種實(shí)現(xiàn)方式,而未對(duì)其進(jìn)行評(píng)估。
因此,本文研究了基于MATLAB 高層次綜合方法,并探究其設(shè)計(jì)效率。首先,本文研究了MATLAB的高層次綜合方法,總結(jié)了一些必要的MATLAB 代碼設(shè)計(jì)風(fēng)格。隨后,建立了一套行之有效的MATLAB 的高層次綜合方法,并確定了作為評(píng)估對(duì)象的電路類型和設(shè)計(jì)方法。最后,本文將同樣的算法邏輯,在Vivado 和MATLAB 中分別實(shí)現(xiàn),并對(duì)編寫(xiě)的模塊進(jìn)行功能性仿真以及時(shí)序仿真,并對(duì)仿真數(shù)據(jù)進(jìn)行性能比較和評(píng)估。最終結(jié)果顯示,在簡(jiǎn)單電路模塊的構(gòu)建上,與Verilog 搭建電路相比,用MATLAB 進(jìn)行設(shè)計(jì),功耗減少程度在-5%~10%區(qū)間內(nèi)波動(dòng),面積使用量增加約5%,時(shí)序減少程度則是-14%~17%不等,主要由于各項(xiàng)數(shù)據(jù)之間的平衡,某項(xiàng)性能的提升會(huì)以另一項(xiàng)性能的降低為代價(jià)。這表明高層次綜合已經(jīng)足夠成熟,并且在特定場(chǎng)合可以在面積,資源利用上實(shí)現(xiàn)突破。
HDL Coder 是MathWorks 推出的一款工具,它支持從MATLAB 代碼自動(dòng)生成HDL 代碼,允許工程師用MATLAB 語(yǔ)言實(shí)現(xiàn)FPGA 和ASIC 設(shè)計(jì)。同時(shí)發(fā)布的還有HDL Verifier,該產(chǎn)品包含用于測(cè)試的FPGA 硬件在環(huán)功能。這兩款產(chǎn)品使得MathWorks可提供利用MATLAB 和Simulink 進(jìn)行HDL 代碼生成和驗(yàn)證的能力[8]。
本文使用的MATLAB 版本為R2019b,HDL Coder 設(shè)計(jì)流程圖如圖1 所示。在新建的腳本文件中以function 的形式確定模塊的功能,同時(shí)明確模塊的輸入和輸出。接著,編寫(xiě)testbench 測(cè)試文件,規(guī)定模塊輸入和輸出數(shù)據(jù)的類型和大小。在命令行窗口中輸入hdlcoder,在彈出的MATLAB HDL Coder Project 窗口中設(shè)置工程名稱以及存放位置。然后在HDL Code Generation 中添加前文提到的function和testbench,最后在workflow advisor 的HDL Code Generation 步驟中,設(shè)置語(yǔ)言為Verilog。在HDL Verification 上右擊選擇運(yùn)行到選定任務(wù),無(wú)報(bào)錯(cuò)即可得到轉(zhuǎn)換的Verilog 代碼。

圖1 HDL Coder 設(shè)計(jì)流程圖
在function 的編寫(xiě)過(guò)程中,由于目前并沒(méi)有較完整的代碼風(fēng)格,編寫(xiě)者大多依靠經(jīng)驗(yàn),我們?cè)趪L試的過(guò)程中發(fā)現(xiàn)了一些可以遵循的規(guī)律。具體地來(lái)說(shuō),我們發(fā)現(xiàn)通過(guò)編寫(xiě)function 和testbench 從MATLAB 函數(shù)中生成Verilog 代碼時(shí),MATLAB 代碼風(fēng)格對(duì)轉(zhuǎn)化結(jié)果起至關(guān)重要的作用,相同邏輯用不合適的語(yǔ)法描述時(shí)可能會(huì)得到不理想的結(jié)果甚至引起報(bào)錯(cuò)。我們探究了不同數(shù)據(jù)類型、輸入、結(jié)構(gòu)語(yǔ)句及MATLAB 中函數(shù)對(duì)生成結(jié)果的影響。結(jié)果如下:
從數(shù)據(jù)類型角度分析:
(1)轉(zhuǎn)化的Verilog 代碼的輸入輸出均為wire類型;
(2)function 中input 與output 的數(shù)據(jù)類型以及長(zhǎng)度大小由testbench 決定,而在MATLAB 中設(shè)置為不同的數(shù)據(jù)類型如logical,double,uint8 等不影響轉(zhuǎn)化結(jié)果,但不可設(shè)置為string,否則fixed-point conversion 階段將不支持;
(3)HDL Coder 不支持2D 矩陣作為function 的輸入,1×n或n×1 矩陣是唯一可以轉(zhuǎn)化的矩陣,轉(zhuǎn)化后變?yōu)閚個(gè)寄存器,寄存器長(zhǎng)度相同且由矩陣中最大的數(shù)值決定。在HDL 程序中由寄存器組作為中間變量進(jìn)行操作。且轉(zhuǎn)化所得的寄存器組完全一致;且輸入輸出矩陣n的大小必須通過(guò)testbench 固定,不支持動(dòng)態(tài)矩陣。
從語(yǔ)法角度分析:
(1)MATLAB 中的switch 語(yǔ)句轉(zhuǎn)化為Verilog 中的case 語(yǔ)句,elseif 語(yǔ)句轉(zhuǎn)化為if 語(yǔ)句,while 語(yǔ)句不支持轉(zhuǎn)化,建議使用for 語(yǔ)句;
(2)較高級(jí)的數(shù)學(xué)函數(shù)不支持轉(zhuǎn)化,已知的有l(wèi)og2(n),dec2bin(),imread()等。
為了更好地研究MATLAB 高層次綜合方法的設(shè)計(jì)效率,本文擬對(duì)數(shù)據(jù)通路的典型電路,具體包括加法器,比較器,數(shù)據(jù)選擇器,乘法器四種電路進(jìn)行設(shè)計(jì)。
算術(shù)邏輯單元(ALU)不僅能完成算術(shù)運(yùn)算也能完成邏輯運(yùn)算,是微處理器芯片中的一個(gè)十分重要的部件[9]。但是所有基本算術(shù)運(yùn)算(加、減、乘、除)最終都可歸結(jié)為加法運(yùn)算,所以加法運(yùn)算的實(shí)現(xiàn)顯得尤為重要[10]。
本文采用四位加法器對(duì)比設(shè)計(jì),考慮到帶有進(jìn)位的加法器設(shè)計(jì),采用的方法為手工擴(kuò)展輸入一位,執(zhí)行常規(guī)加法,截取和的最高位作為進(jìn)位。
在MATLAB 的腳本文件中,編寫(xiě)代碼得到兩個(gè)輸入相加的和,再把和分為進(jìn)位以及非進(jìn)位部分,如圖2(a)所示,再編寫(xiě)測(cè)試文件,由于MATLAB HDL Coder 的特殊性,需要在激勵(lì)文件中通過(guò)給輸入輸出賦值,來(lái)達(dá)到約束位數(shù)的作用,如針對(duì)此加法器,x1 和x2 的賦值區(qū)間在[8,15]時(shí),轉(zhuǎn)化生成的Verilog 代碼中的輸入為4 位2 進(jìn)制。同理,如果賦值區(qū)間為[16,31],得到的轉(zhuǎn)化代碼中input 的位數(shù)也就為5 位。因此如圖2(b)中,給x1 和x2 賦值為15,使得約束加法器的輸入為4 位2 進(jìn)制,就可以得到相同原理的四位加法器模塊。

圖2 基于HDL Coder 的加法器代碼
在數(shù)字電路中,數(shù)值比較器的輸入是要進(jìn)行比較的兩個(gè)二進(jìn)制數(shù),輸出是比較的結(jié)果[11],是一種比較常見(jiàn)且很常用的邏輯模塊。
本文采用最基本的32 位比較器,即輸入的數(shù)均為字長(zhǎng)為一個(gè)字節(jié)的無(wú)符號(hào)整型數(shù),通過(guò)比較大小輸出相應(yīng)的結(jié)果值。輸出三個(gè)值x、y、z初始均為0,若a>b,則x變?yōu)?;若a=b,則y變?yōu)?;若a<b,則z變?yōu)?。
在腳本文件中新建function comp_1,如圖3,在此函數(shù)中,編寫(xiě)基本比較器的邏輯,即當(dāng)a>b時(shí),x=1,y=0,z=0;即當(dāng)a=b時(shí),x=0,y=1,z=0;即當(dāng)a<b時(shí),x=0,y=0,z=1。整個(gè)函數(shù)通過(guò)三個(gè)if 結(jié)構(gòu)來(lái)完成。

圖3 比較器代碼
數(shù)據(jù)選擇器(也稱多路選擇器)是一種多輸入、單輸出的組合邏輯電路,在地址端的控制下將多個(gè)輸入信號(hào)中的一個(gè)從輸出端輸出[12]。數(shù)據(jù)選擇器屬于組合邏輯電路,他的基本功能是在數(shù)據(jù)傳輸過(guò)程中完成多路數(shù)據(jù)到一路數(shù)據(jù)的有序轉(zhuǎn)換,還可代替繁多的邏輯門實(shí)現(xiàn)組合邏輯函數(shù),從而使電路簡(jiǎn)化[13],因此也是個(gè)十分重要的模塊。
本文選用的是四位四選一數(shù)據(jù)選擇器,通過(guò)判斷輸入的值來(lái)選擇哪個(gè)通路的數(shù)據(jù)被輸出。
如圖4,在MATLAB 的腳本文件中通過(guò)case 結(jié)構(gòu)實(shí)現(xiàn),當(dāng)a 的取值分別為00、01、10、11 時(shí),輸出端out 將分別輸出in0,in1,in2,in3 的數(shù)據(jù)。

圖4 數(shù)據(jù)選擇器代碼
在各類處理器中,乘法器有著不可或缺的地位。高性能的乘法器是提高中央處理器運(yùn)算速度的關(guān)鍵。在常見(jiàn)的FPGA 芯片上都不會(huì)搭載多位乘法器模塊,需要我們進(jìn)行設(shè)計(jì)來(lái)實(shí)現(xiàn),所以研究FPGA 的數(shù)字乘法器是有著非常重要的意義。在乘法器設(shè)計(jì)上,以位移相乘法和booth 算法居多[14]。本文主要研究采用位移相乘法的乘法器模塊。
本文研究基本的16 位乘法器模塊,算法為從乘數(shù)的最末尾開(kāi)始依次與被乘數(shù)相乘,并將乘得的結(jié)果依次左移再相加求和。
如圖5 所示,在MATLAB 的腳本文件中,編寫(xiě)代碼得到兩個(gè)輸入相乘的積。

圖5 乘法器代碼
此次對(duì)比測(cè)試中,我們選擇FPGA 板卡型號(hào)為xc7k325tffg900-2。仿真的過(guò)程中,我們分別將直接編寫(xiě)的Verilog 代碼與MATLAB 轉(zhuǎn)化后生成的Verilog 代碼使用Vivado 進(jìn)行仿真。
單個(gè)模塊差異過(guò)小,如功耗差異出現(xiàn)在小數(shù)點(diǎn)后3位以上,造成無(wú)法比較。為了解決這個(gè)問(wèn)題,我們將兩份代碼進(jìn)行處理,處理的方法即在新建的頂層模塊中使用generate 語(yǔ)句,生成函數(shù)名為<模塊名>bit[0].f1到<模塊名>bit[999].f1 的1 000 個(gè)相同的該模塊,這樣可以便捷地實(shí)現(xiàn)1 000 個(gè)相同功能模塊的并行,使得兩份代碼在增加功耗的同時(shí)消除錯(cuò)誤影響。
同時(shí),1 000 個(gè)輸出的末端可能出現(xiàn)“線與”的問(wèn)題,此問(wèn)題主要體現(xiàn)在造成了電路末端信號(hào)的冒險(xiǎn)與競(jìng)爭(zhēng),在妨礙正常波形輸出(產(chǎn)生毛刺等錯(cuò)誤)的同時(shí)還增加了不確定的功耗,導(dǎo)致兩者的對(duì)比結(jié)果不準(zhǔn)確,乃至導(dǎo)致結(jié)論錯(cuò)誤。因此,為了避免這一問(wèn)題,我們?cè)诿總€(gè)模塊的末端增加數(shù)據(jù)選擇器,并且在輸出的每一位bit 處使用或門得到正確的輸出。這樣雖然增加了功耗,但是每個(gè)模塊的增加功耗相同。因此,差異不會(huì)改變,最終也就可以正確地得出所有結(jié)論。
在Vivado 中編寫(xiě)每個(gè)頂層模塊的testbench,其中在每個(gè)激勵(lì)文件中,利用random 函數(shù)每過(guò)30 ns隨機(jī)生成給定范圍內(nèi)的激勵(lì)信號(hào),使得仿真生成的saif 向量文件輔助測(cè)試功耗有較高的可信度。
將代碼改寫(xiě)后,我們先將工程進(jìn)行綜合以及實(shí)現(xiàn),對(duì)代碼進(jìn)行布局布線之后才能獲得準(zhǔn)確的功耗以及資源利用情況。在做完實(shí)現(xiàn)之后,根據(jù)官方提供的手冊(cè)u(píng)g997 進(jìn)行時(shí)序仿真,來(lái)生成saif 向量文件,這個(gè)向量文件用以獲得置信水平為high 的功耗報(bào)告。這樣通過(guò)對(duì)兩份代碼的仿真,分別獲得溫度、功耗,時(shí)序,原理圖,資源等數(shù)據(jù),并且確保了置信水平為high。
我們通過(guò)對(duì)比兩種代碼的功耗,資源,原理圖,時(shí)序等(如表1),發(fā)現(xiàn)了以下的結(jié)論:Verilog 編寫(xiě)在復(fù)雜電路中總體更優(yōu),但高級(jí)語(yǔ)言的HDL 各項(xiàng)數(shù)據(jù)也較為接近,在簡(jiǎn)單電路中表現(xiàn)甚至更為優(yōu)秀,具體的數(shù)據(jù)差異體現(xiàn)在功耗、時(shí)間、面積的相互轉(zhuǎn)換上,即一項(xiàng)性能的提升會(huì)帶來(lái)另一項(xiàng)性能的降低。

表1 四種基本運(yùn)算模塊的性能對(duì)比
我們采用式(1)來(lái)計(jì)算MATLAB HLS 的性能改進(jìn)程度:

該公式僅用于計(jì)算功耗、IO、LUT,對(duì)于WNS 則不需要公式前的負(fù)號(hào)。計(jì)算所得的百分比若為正則表示性能的提升,為負(fù)則表示性能的下降。
由表可知,使用MATLAB HLS,在加法器的設(shè)計(jì)上功耗優(yōu)化了11.50%,面積優(yōu)化了2.11%,時(shí)延優(yōu)化了16.12%,再者,數(shù)據(jù)選擇器設(shè)計(jì)功耗優(yōu)化了0.96%,時(shí)延快2.39%,但面積多出來(lái)0.92%;比較器的優(yōu)勢(shì)主要集中在功耗上,優(yōu)化28.96%。由此看來(lái),在簡(jiǎn)單電路的構(gòu)建上,MATLAB 高層次綜合與Verilog 搭建電路相比,性能指標(biāo)的差異主要集中在功耗、時(shí)間和面積的相互轉(zhuǎn)化上。但針對(duì)復(fù)雜電路如乘法器電路,功耗、面積以及時(shí)延皆不如Verilog編寫(xiě)的代碼,具體的差距分別為0.09%,9.29%和11.43%??梢?jiàn),高級(jí)語(yǔ)言的HLS 在復(fù)雜電路的轉(zhuǎn)化和優(yōu)化上還有很長(zhǎng)的路要走。
在此基礎(chǔ)上,繼續(xù)測(cè)試了不同位寬下MATLAB HLS 和Verilog 直接編寫(xiě)代碼的性能對(duì)比。當(dāng)位寬為4 位、8 位、16 位、32 位依次增長(zhǎng)時(shí),兩種設(shè)計(jì)方式的功耗、LUT 呈現(xiàn)上升的趨勢(shì),WNS 呈現(xiàn)下降的趨勢(shì),這也是意料之內(nèi)的結(jié)果。
在上述設(shè)計(jì)的基礎(chǔ)上進(jìn)行不同位寬下的性能對(duì)比,我們?nèi)匀徊捎檬?1)來(lái)計(jì)算功耗、LUT 和WNS的性能改進(jìn)程度,其中以加法器的不同位寬性能對(duì)比為例,計(jì)算功耗、LUT 使用以及WNS 的性能提升百分比,如圖6 所示,位寬為4 位時(shí)MATLAB HLS全面占優(yōu),而位寬為8 位時(shí),僅速度優(yōu)于直接編寫(xiě)的代碼,在16 位加法器中則為面積占優(yōu),最后32 位加法器只有面積劣于Verilog 直接編寫(xiě)的代碼。隨著位數(shù)的增加,性能的差異沒(méi)有一成不變,而是體現(xiàn)在功耗、時(shí)間、面積的相互轉(zhuǎn)換上。如圖7 所示,數(shù)據(jù)選擇器也是同理。

圖6 加法器不同位寬性能對(duì)比

圖7 數(shù)據(jù)選擇器不同位寬性能對(duì)比
但對(duì)于乘法器這種復(fù)雜電路來(lái)說(shuō),如圖8 所示,僅在4 位和8 位電路相對(duì)簡(jiǎn)單時(shí),MATLAB HLS 在速度上稍占優(yōu)勢(shì),隨著位數(shù)的增加,電路復(fù)雜度的提升,在16 位和32 位時(shí)性能全面處于劣勢(shì),但劣勢(shì)不是很大,32 位時(shí)功耗和面積分別低3.39%和0.88%,也就是說(shuō)MATLAB HLS 在復(fù)雜電路的轉(zhuǎn)化上還有一定的提升空間,但Verilog 直接編寫(xiě)代碼的優(yōu)勢(shì)也不明顯。折線圖依然可以體現(xiàn)功耗、時(shí)間、面積性能的相互轉(zhuǎn)換。

圖8 乘法器不同位寬性能對(duì)比
本文研究了基于MATLAB 的高層次綜合方法,并用該方法完成了加法器、比較器、四選一數(shù)據(jù)選擇器、乘法器這些運(yùn)算模塊的設(shè)計(jì)。在與傳統(tǒng)的RTL級(jí)設(shè)計(jì)的功能與時(shí)序仿真對(duì)比中,得知使用MATLAB 進(jìn)行高層次綜合的設(shè)計(jì)功耗減少程度在-5%~10%區(qū)間內(nèi)波動(dòng),面積使用量約增加5%,時(shí)序減少程度則是-14%~17%不等,主要為各項(xiàng)數(shù)據(jù)之間的平衡。評(píng)估結(jié)果顯示,現(xiàn)階段使用高級(jí)語(yǔ)言如MATLAB 進(jìn)行高層次綜合的設(shè)計(jì)已經(jīng)成為了可能,在性能差距可以接受的前提下,MATLAB 高層次綜合已經(jīng)足夠成熟,并且在特定場(chǎng)合可以在面積,資源利用上實(shí)現(xiàn)突破。