增量式編譯QIC大幅縮短FPGA編譯時(shí)間
前言
按照相對論的理論,時(shí)間也是可以被拉長縮短的,只不過需要巨大的能量支撐著您達(dá)到一個(gè)和光速可比擬的高速度而已。這話說著輕松,你我心里都明白,估計(jì)咱們的有生之年是看不到這樣的情景的……
回到可編程邏輯器件領(lǐng)域,隨著65nm、40nm,乃至目前的28nm深亞微米工藝的采用,廠家生產(chǎn)出了越來越大,也越來越復(fù)雜的FPGA器件。而用戶們在為FPGA不斷增強(qiáng)的功能和不斷下降的單位成本而欣喜不已的同時(shí),也在為相關(guān)EDA軟件的性能滯后所帶來的開發(fā)效率相對降低而苦惱不已,尤其是對大容量FPGA芯片動輒10到20個(gè)小時(shí)的編譯時(shí)間可謂怨氣沖天。筆者在許多次面對一線的FPGA工程師時(shí),都聽到了這樣類似的話:要是編譯時(shí)間能壓一壓就好了!
Altera不能真的壓縮時(shí)間,但我們能改變“速度”!從數(shù)年前的版本開始,Quartus2軟件中就整合了一種新技術(shù),或者說一種新的設(shè)計(jì)流程:增量式編譯(Incremental Compilation)。它是ALTERA為解決大容量FPGA設(shè)計(jì)編譯時(shí)間太長的問題給出的一個(gè)新式工具!您,了解它嗎?
增量式編譯原理及流程
增量式編譯QIC的原理很容易理解:對一個(gè)復(fù)雜的設(shè)計(jì)而言,肯定是需要做一定的功能劃分,由不同的子功能模塊來實(shí)現(xiàn)。那么在設(shè)計(jì)進(jìn)入后期比較成熟的時(shí)候,前后兩次編譯的設(shè)計(jì)版本中,會有很大部分的電路邏輯都是相同的(沒有修改),如果能在后一次編譯中,重復(fù)利用前一次編譯中未改變部分的編譯結(jié)果,也就是相應(yīng)部分的布局布線信息,那么就能把這部分邏輯所消耗的布局布線時(shí)間節(jié)約下來,從而在很大程度上縮短整個(gè)設(shè)計(jì)的編譯時(shí)間。當(dāng)然,聰明的讀者都能想到,這樣的編譯方式,除了能縮短編譯時(shí)間,還能支持許多別的用途,比如IP設(shè)計(jì)交付、團(tuán)隊(duì)開發(fā)、不改變正常設(shè)計(jì)結(jié)果插入調(diào)試接口等。這些確實(shí)都是ALTERA 增量式編譯能夠?qū)崿F(xiàn)的功能,但在本文中我們只闡述QIC在縮短編譯時(shí)間方面的作用。
增量式編譯原理雖然簡單,但要在FPGA的EDA軟件中實(shí)現(xiàn),卻是一個(gè)復(fù)雜的系統(tǒng)工程。它不是簡單地在軟件中增加一個(gè)功能模塊,而是對編譯處理流程多方面的改變和增強(qiáng)!請比較圖1和圖2兩幅附圖:圖1是傳統(tǒng)的FPGA編譯流程(Altera名稱:Flat compilation),圖2則是增量式編譯流程的示意圖。我們很容易發(fā)現(xiàn)增量式編譯流程復(fù)雜了許多,不僅引入了一些新的概念,比如設(shè)計(jì)分區(qū)(partition)、分區(qū)綜合后網(wǎng)表、分區(qū)布局/布線后網(wǎng)表等,同時(shí)加入了新的處理階段——分區(qū)合并(partition merging),而且對分析綜合(Analysis&Synthesis)和布局布線(fitter)階段進(jìn)行了改進(jìn),增加了許多針對分區(qū)的具體操作。
圖1 Flat Compilation 流程
圖2 QIC增量式編譯流程
經(jīng)過幾年的研究與實(shí)踐,QuartusII的增量式編譯已逐步完善,無論是在可操作性、穩(wěn)健性方面,還是在縮短編譯時(shí)間的效果方面,都十分出色。筆者參與的幾個(gè)客戶項(xiàng)目中,通過QIC的實(shí)施,都得到了50%左右的編譯時(shí)間節(jié)約,極大提高了客戶的開發(fā)效率。下面,我將結(jié)合這些實(shí)際項(xiàng)目中的經(jīng)驗(yàn),介紹如何實(shí)踐利用QIC來高效的縮短設(shè)計(jì)編譯時(shí)間。
QIC實(shí)踐
QIC的效果評估
在討論具體如何使用QIC之前,先考慮一個(gè)問題:如果讀者在您的工作中使用了增量式編譯QIC,怎么評估它的效能呢?
您需要至少做3輪實(shí)驗(yàn),才能看到QIC節(jié)約編譯時(shí)間的效果。首先,需要把您的設(shè)計(jì)用傳統(tǒng)編譯流程Flat Compilation進(jìn)行編譯,記錄下各階段所花費(fèi)的時(shí)間。然后,創(chuàng)建合理的設(shè)計(jì)分區(qū),指定分區(qū)網(wǎng)表性質(zhì),進(jìn)行第二次編譯,得到QIC各個(gè)分區(qū)的初始網(wǎng)表,并請記錄下操作時(shí)間。第三次編譯,您可以選擇修改設(shè)計(jì)中的某一個(gè)分區(qū),然后再編譯一次,記錄下操作花費(fèi)的時(shí)間。將第三次的編譯時(shí)間和第一次相比,正常的話應(yīng)當(dāng)看到非常明顯的時(shí)間節(jié)約,這才是QIC增量式編譯在編譯時(shí)間節(jié)約方面的體現(xiàn)。
值得注意的是,第二次編譯中已經(jīng)使用了QIC,但往往花費(fèi)時(shí)間和第一次編譯差不多,有時(shí)還有增長。許多人為此懷疑QIC的性能,認(rèn)為QIC沒有效果甚至惡化了編譯時(shí)間。這其實(shí)是一種誤解!為什么呢?回到圖2,我們可以看到,QIC流程在Analysis&Synthesis和fitter之間增加了一個(gè)新的處理階段——分區(qū)合并,它是需要額外花費(fèi)在第一次Flat Compilation中不存在的時(shí)間。而且,由于這是創(chuàng)建分區(qū)后的第一次編譯,所有分區(qū)的網(wǎng)表都是空白的,也就是說整個(gè)設(shè)計(jì)都需要被編譯、分析、綜合、布局布線等的工作量和第一次編譯是類似的,因此這部分花費(fèi)的時(shí)間也是差不多。把這兩部分時(shí)間加起來,自然第2次編譯時(shí)間有可能會比第一次長了。只有當(dāng)進(jìn)行第3次編譯的時(shí)候,各個(gè)分區(qū)都有可重用的網(wǎng)表了,才有可能將那些沒有設(shè)計(jì)改變的分區(qū)的網(wǎng)表重用,從而節(jié)約綜合和布局布線階段的時(shí)間,達(dá)到整體編譯時(shí)間的節(jié)約。
圖3是筆者支持的一個(gè)客戶所進(jìn)行的QIC增量式編譯性能評估的結(jié)果總結(jié)??蛻舻脑O(shè)計(jì)是高端路由器中的包處理應(yīng)用,使用了ALTERA公司的Stratix4GX530器件,邏輯利用率大約是60%。客戶的編譯硬件是一臺高性能服務(wù)器:
圖3 Z客戶增量式編譯評估實(shí)驗(yàn)效果
CPU:16core Intel(R) Xeon(R) CPU E7420 @2.13GHz
Memory:64GB
即使是如此,在不使用QIC的情況下,客戶的每次編譯都需要12到13個(gè)小時(shí)。而在使用QIC并根據(jù)QIC指導(dǎo)原則進(jìn)行了必要的設(shè)計(jì)優(yōu)化后,最好的實(shí)驗(yàn)結(jié)果是可以在6個(gè)小時(shí)左右(大約350分鐘)完成一次編譯,節(jié)約了接近55%的總編譯時(shí)間!從圖3中很容易看出前面文字描述的幾個(gè)特點(diǎn):
第一次編譯和第二次編譯的總時(shí)間差不多(750 VS 730)
第三次編譯中,Analysis&Synthesis操作的時(shí)間,fitter操作得時(shí)間都比第一次編譯有非常明顯的降低;
從原理上看,QIC的網(wǎng)表重用對Assembly和時(shí)序分析沒有直接影響。因此三次編譯中,Assembler和時(shí)序分析所花費(fèi)的時(shí)間是差不多的。
QIC指導(dǎo)原則
合理創(chuàng)建分區(qū)
Quartus中的“分區(qū)”是和設(shè)計(jì)層次緊密關(guān)聯(lián)的。任何設(shè)計(jì),無論簡單還是復(fù)雜,都會有一個(gè)頂層模塊(top-level module),Quartus自動將它設(shè)置為一個(gè)默認(rèn)分區(qū)(命名為top),不需要用戶設(shè)定。而別的分區(qū),需要用戶手動創(chuàng)建。創(chuàng)建分區(qū)的方法很簡單,在Quartus GUI界面左上角的Hierarchy窗口,選擇想創(chuàng)建分區(qū)的實(shí)體,右鍵喚出的菜單中選擇“Design Partition”,然后在下一級菜單中選擇”Setting as Design Partition”,分區(qū)就創(chuàng)建成功了。
從圖2可以看出,分區(qū)(Partition)是增量式編譯中的一個(gè)關(guān)鍵概念。Altera規(guī)定:只要是有完整設(shè)計(jì)邊界的設(shè)計(jì)實(shí)體,無論它在設(shè)計(jì)的哪一層次,都可以用它來創(chuàng)建設(shè)計(jì)分區(qū)。也就是說,Quartus II中,設(shè)計(jì)中任何層次中的任何一個(gè)設(shè)計(jì)模塊,可以作為一個(gè)設(shè)計(jì)分區(qū);一個(gè)設(shè)計(jì)中也可以包含不止一個(gè)設(shè)計(jì)分區(qū);即使是在設(shè)計(jì)的同一層次,也可有多個(gè)分區(qū)。同時(shí),請注意:分區(qū)之間沒有層次關(guān)系,任何邏輯只能歸屬于某一個(gè)分區(qū)。以圖5為例,A模塊由A1、B1、C1三個(gè)子模塊組成。如果A模塊被設(shè)置為分區(qū),Quartus會用模塊名來為此分區(qū)命名:A分區(qū)。那么,A分區(qū)中就會包含A1、B1、C1三個(gè)子模塊的所有邏輯。但如果把B1子模塊也創(chuàng)建為分區(qū),那么,A分區(qū)中就只包含A1、C1兩個(gè)子模塊的邏輯,B1子模塊的邏輯只屬于新的B1分區(qū)了。
圖4 在Quartus GUI中創(chuàng)建分區(qū)示意
圖5 分區(qū)與邏輯歸屬變化
圖6 分區(qū)合并報(bào)告
圖7 分區(qū)綜合后資源使用統(tǒng)計(jì)
圖8 Design partition window
圖9 Design partition window
從前面分區(qū)的性質(zhì)和特點(diǎn)可以看出,對包含多個(gè)功能模塊的多層次復(fù)雜設(shè)計(jì),可以有許多種設(shè)置分區(qū)的方案。但需要注意的是:不是任何一種分區(qū)方案都能帶來編譯時(shí)間的節(jié)約,惡劣的設(shè)計(jì)分區(qū)甚至能夠?qū)е戮幾g失敗!如何得到高效合理的設(shè)計(jì)分區(qū)呢?我們需要遵從以下原則:
a. 不要?jiǎng)?chuàng)建太多的分區(qū),一般性的設(shè)計(jì)建議分區(qū)的數(shù)量控制在4~8個(gè)之間;
b. 不要?jiǎng)?chuàng)建太小的分區(qū),一般建議不要小于1000個(gè)LE或者ALM;
c. 外設(shè)接口邏輯和內(nèi)核處理邏輯放到不同的設(shè)計(jì)分區(qū);
d. 相同或相近功能的外設(shè)接口,如果管腳位置相鄰,可以放在同一個(gè)分區(qū),否則創(chuàng)建不同的設(shè)計(jì)分區(qū);
e. 不同的分區(qū)方案中,分區(qū)之間的聯(lián)接少的方案更優(yōu)。
針對QIC優(yōu)化代碼
除了分區(qū)方案,設(shè)計(jì)代碼也對QIC的性能有直接的影響,需要設(shè)計(jì)者針對QIC做一些特定的代碼優(yōu)化。優(yōu)化主要有兩方面,一方面是升級所使用的Megacore IP到最新的版本;另一方面則是一些更嚴(yán)格的編碼規(guī)則。
之所以建議升級Megacore IP到最新的版本,這是由于QIC增量式編譯常常需要調(diào)用Megacore IP的一些特性來支持一些特定操作,而這些特性通常在較新的版本中才能得到比較好的支持,而且隨著QIC的成熟不斷改進(jìn)。筆者就曾經(jīng)在一個(gè)嘗試使用QIC的項(xiàng)目中,發(fā)現(xiàn)客戶的設(shè)計(jì)繼承了一部分老項(xiàng)目中的代碼,其中包含好幾個(gè)Quartus 9.1版本的DDR EMIF控制器,占了整個(gè)設(shè)計(jì)使用資源的20%左右。當(dāng)說服客戶把這幾個(gè)控制器升級到當(dāng)時(shí)最新的Quartus 11版本,發(fā)現(xiàn)QIC所能節(jié)約的編譯時(shí)間增加了近1個(gè)小時(shí),大約15%的整體編譯時(shí)間。
之所以QIC要求遵從更嚴(yán)格的編碼規(guī)則,這是由于Quartus在有分區(qū)存在的時(shí)候,是不對跨越分區(qū)邊界的邏輯進(jìn)行綜合優(yōu)化,一些在Flat compilation中可以被軟件優(yōu)化掉的不良代碼,在QIC的流程中會造成嚴(yán)重的影響。這些嚴(yán)格的編碼規(guī)則包括:
不要在底層分區(qū)邊界上使用三態(tài)信號和雙向端口;
Altera器件中,只有在器件的輸出管腳上才能實(shí)現(xiàn)真正的三態(tài)信號,在器件內(nèi)部,三態(tài)驅(qū)動是依靠多路器邏輯模擬實(shí)現(xiàn),這兩點(diǎn)往往要求跨層的編譯優(yōu)化,而這在增量式編譯流程中是做不到的,會導(dǎo)致編譯失敗。只有一種情形例外,就是內(nèi)部三態(tài)邏輯所涉及的所有信號都在同一個(gè)底層分區(qū)中,Quartus可以依靠多路器邏輯模擬此三態(tài)邏輯。雙向端口也類似,只有在此雙向邏輯所涉及的所有信號都在一個(gè)底層分區(qū)中,QIC才能正常進(jìn)行。
分區(qū)的輸入輸出最好都通過寄存器實(shí)現(xiàn),資源有限的情況下至少保證跨分區(qū)的連接中的一端是寄存器(reg-in或者reg-out);
雖然這一規(guī)則有一定的實(shí)現(xiàn)難度,但它可以避免在使用增量式編譯流程的時(shí)候,那些跨分區(qū)邊界的信號的延遲出現(xiàn)大的惡化。如果不能實(shí)現(xiàn)這一規(guī)則,跨分區(qū)連接的兩端有可能都是組合邏輯。在Flat Compilation中,這兩組組合邏輯會被綜合優(yōu)化到一起來布局布線,時(shí)序容易滿足;但在是增量式編譯中,由于不能跨區(qū)優(yōu)化,這2組組合邏輯的分別布局布線,那穿過這兩組邏輯的路徑延遲將有可能變得很長,出現(xiàn)時(shí)序違背。
避免不包含任何處理邏輯的信號環(huán)路穿越分區(qū)邊界;
也是由于不能跨區(qū)優(yōu)化,這樣的信號環(huán)在Flat Compilation中可以被優(yōu)化消除掉,在增量式編譯中就不能消除,浪費(fèi)資源。
避免跨分區(qū)的常量信號
類似C,跨區(qū)的常量信號不能在目的端分區(qū)中直接實(shí)現(xiàn)(“0”連接地層,“1”連接電源層),而必須占用走線資源實(shí)現(xiàn)。
關(guān)注相關(guān)報(bào)告信息
使用QIC時(shí),Quartus中會產(chǎn)生很多QIC專有的消息,因此在編譯報(bào)告中也增加一些新的章節(jié)。這些報(bào)告章節(jié),對我們了解QIC的運(yùn)行情況有直接的幫助,尤其是當(dāng)一些異常情況出現(xiàn),往往需要我們通過閱讀這些報(bào)告章節(jié)來進(jìn)行調(diào)試。比較重要的報(bào)告有:
a. Partition Merge report
分區(qū)合并的報(bào)告章節(jié)如下圖所示,分別提供在這個(gè)階段網(wǎng)表的使用情況(netlist Types Used),各個(gè)分區(qū)的綜合警告信息(Partition Warning)和綜合后各類資源使用情況(Partition Statistics)。
b. Incremental compilation section in Fitter report
在Fitter報(bào)告中,也增加了增量式編譯的章節(jié)。其中,Incremental Compilation Preservation Summary匯總了設(shè)計(jì)中被保留的布局和布線比例;Incremental Compilation Partition setting 說明了設(shè)計(jì)中所有分區(qū)的創(chuàng)建方式和網(wǎng)表的保留級別(Preservation level);Incremental Compilation Placement Preservation給出了每一個(gè)分區(qū)中節(jié)點(diǎn)保留的信息;Incremental Compilation Routing Preservation則是每個(gè)分區(qū)中布線保留的信息。
c. Design partition window
這個(gè)窗口默認(rèn)是不在Quartus 界面中顯示的,用戶需要通過Quartus菜單欄“Assignments”->”Design partition window”打開這個(gè)窗口。這個(gè)窗口給出可配置分區(qū)的當(dāng)前設(shè)置及各個(gè)網(wǎng)表文件的時(shí)間戳信息,并且可以在此窗口中快速修改分區(qū)使用的網(wǎng)表類型(Netlist Type)和Fitter網(wǎng)表的保留級別(Fitter Preservation Level)。
結(jié)束語
在本文中,向大家介紹了增量式編譯的原理、過程和一些性能表現(xiàn),同時(shí)給出了使用QIC需要注意的一些指導(dǎo)原則。華為、中興等客戶的多個(gè)項(xiàng)目實(shí)踐已經(jīng)證明QIC是一個(gè)可以用來解決大容量FPGA設(shè)計(jì)編譯時(shí)間太長的有效手段。增量式編譯QIC,值得您去嘗試!