綜合工具-Design Compiler使用(從RTL到綜合出各種報(bào)告timing\area\critical_path)
????????之前講過(guò)gvim、vcs、makefile的使用,相當(dāng)于自己寫(xiě)出一個(gè)RTL代碼,可以實(shí)現(xiàn)編譯、仿真及腳本自動(dòng)化控制操作。
????????本篇專欄講講自己寫(xiě)出一個(gè)RTL code之后如何對(duì)其進(jìn)行綜合,能夠看到我們寫(xiě)的代碼的timing報(bào)告、面積報(bào)告以及critical path。

????????邏輯綜合(synthesis)就是將前端設(shè)計(jì)工程師編寫(xiě)的RTL代碼,映射到特定的工藝庫(kù)上,通過(guò)添加約束信息,對(duì)RTL代碼進(jìn)行邏輯優(yōu)化,形成門(mén)級(jí)網(wǎng)表。
????????整個(gè)ASIC設(shè)計(jì)可以如下描述:
????????產(chǎn)生想法->說(shuō)明文檔spec->根據(jù)文檔編寫(xiě)RTL code->RTL仿真/驗(yàn)證->綜合產(chǎn)生門(mén)級(jí)網(wǎng)表->物理布局布線->tape out。
????????對(duì)于邏輯綜合步驟來(lái)說(shuō),我們通常使用的工具為Design Compiler,將一個(gè)RTL code在DC里做綜合時(shí),工具會(huì)先將代碼轉(zhuǎn)換成一個(gè)GTECH網(wǎng)表(generic technology (GTECH)netlist),然后在映射不同的工藝庫(kù)形成真正的門(mén)級(jí)網(wǎng)表。
????????具體的實(shí)現(xiàn)思路就是:
????????①先加載工藝庫(kù)(是使用臺(tái)積電的,還是中芯國(guó)際的,又是多少納米的?是一個(gè).db文件)和RTL文件。
????????②添加時(shí)序約束和設(shè)計(jì)約束。(添加約束后工具才能根據(jù)你下的約束做邏輯優(yōu)化)
????????③得到工藝庫(kù)+RTL設(shè)計(jì)+約束文件后,就可以進(jìn)行綜合了。
????????④綜合完畢,就要對(duì)綜合的結(jié)果進(jìn)行分析??磿r(shí)序報(bào)告、面積報(bào)告、功耗報(bào)告。看這些報(bào)告看有沒(méi)有出現(xiàn)一些錯(cuò)誤。
????????⑤如果有問(wèn)題就改設(shè)計(jì),如果沒(méi)有問(wèn)題,就導(dǎo)出成一個(gè)ddc的網(wǎng)表,提供給后端人員做布局布線。

????????在DC中有兩種library,target library 和 link library;其中target library是你在做綜合的時(shí)候,使用的庫(kù)(可以使用代碼段:set_app_var target_library 90nm_typical.db 指定target library)。一般來(lái)說(shuō)在設(shè)計(jì)里面把 link library 和?target library 都指定為同一個(gè),只有在要修改設(shè)計(jì)所綜合工藝時(shí)才會(huì)改link library,舉個(gè)例子,如果需要將已有的設(shè)計(jì)從一個(gè)工藝 A 轉(zhuǎn)到另一個(gè)工藝 B 時(shí),可以將當(dāng)前單元綜合庫(kù) A 設(shè)為 link_library,而將單元綜合庫(kù) B 設(shè)為 target_library ,重新映射一下即可,之所以說(shuō)一般設(shè)定為一個(gè)值,因?yàn)橐髌覍?duì)應(yīng)的廠商一般工藝都是確定的,所以不會(huì)中途要修改工藝的情況,這個(gè)了解一下就好。
????????在使用DC前,如果是第一次使用,需要指定一個(gè)library的工作目錄,以及指定所使用的target library和link library。
????????指定完使用的庫(kù)之后,DC工具需要讀入RTL文件,使用命令:read_verilog "TOP.v a.v b.c",輸入了三個(gè).v的設(shè)計(jì)文件。
????????但是我們通常會(huì)有很多RTL文件,但是只有一個(gè)頂層文件,所以需要指定一下告訴DC工具哪個(gè)是頂層,使用代碼:current_design TOP。就可以指定module TOP為整個(gè)項(xiàng)目的頂層,要注意的是這里的TOP指的是module名,而不是文件名。
????????讀入設(shè)計(jì)后,需要加時(shí)序約束,要下的時(shí)序約束有很多,比如說(shuō):
????????① 期望時(shí)鐘的時(shí)鐘頻率是多少?create_clock -period 10?[get_ports CLK]? ?(創(chuàng)建一個(gè)時(shí)鐘,時(shí)鐘的周期為10ns,對(duì)應(yīng)的端口名為CLK。)
????????② 時(shí)鐘的抖動(dòng)為多少?set_clock_uncertainty -setup 0.3 [get_clocks CLK] (設(shè)置時(shí)鐘沿的抖動(dòng)為0.3ns,可能提前0.3,也可能落后0.3ns)
????????③ 時(shí)鐘的翻轉(zhuǎn)時(shí)間為多少? set_clock_transition -max 0.15 [get_clocks CLK](這個(gè)設(shè)置的原因是,我們理想的時(shí)鐘翻轉(zhuǎn)時(shí)間是為0的,直上直下,但實(shí)際上時(shí)鐘的翻轉(zhuǎn)跳變是需要時(shí)間的,并非直上直下,這條代碼就是設(shè)置時(shí)鐘的翻轉(zhuǎn)時(shí)間為0.15ns)
????????④ 時(shí)鐘延時(shí)為多少?set_clock_latency -max 0.7 [get_clocks CLK] (時(shí)鐘的傳播是有時(shí)間的,從產(chǎn)生時(shí)鐘的晶振到需要時(shí)鐘的模塊,中間的傳輸時(shí)間為多少?就是這里設(shè)置的clock_latency)
????????⑤ 輸入延時(shí)(input_delay)為多少?set_input_delay -max 0.6 -clock CLK [get_ports A](這個(gè)是針對(duì)數(shù)據(jù)來(lái)的,數(shù)據(jù)從時(shí)鐘邊沿開(kāi)始,最延時(shí)多久才能從輸入端口進(jìn)來(lái))
????????⑥ 輸出延時(shí)(output_delay)為多少?set_output_delay -max 0.8 -clock CLK [get_ports B] (輸出可接受最大延時(shí)為多少,然后DC根據(jù)你下的約束去綜合內(nèi)部的組合邏輯)
????????⑦ 輸入傳輸延時(shí)為多少? set_input_transition 0.12 [get_ports A],輸入的數(shù)據(jù)的翻轉(zhuǎn)也不是理想的,從0-1的翻轉(zhuǎn)并非直上直下,需要一定的時(shí)間。

Performs three levels of optimization 優(yōu)化主要從三個(gè)方面進(jìn)行
1.Architectural level synthesis? ? ? ? ? ? ? ? ? ? ? ?--架構(gòu)優(yōu)化 插入buffer等
2.Logic level or GTECH optimization???????? ?? --邏輯優(yōu)化 卡諾圖化簡(jiǎn)等
3.Gate-level or mapping optimization? ? ? ? ? ? --門(mén)級(jí)優(yōu)化 選擇用大與門(mén),小與門(mén)等
優(yōu)化的條件:先滿足時(shí)序約束,再優(yōu)化面積。Minimize area while meeting timing constrain
編譯完了之后下面就是看我們的綜合報(bào)告了
????????輸入:report_qor 查看綜合的概況(quality of result 即qor) ,可以看到關(guān)鍵路徑的長(zhǎng)度、裕量、周期、面積等。

????????輸入 report_timing 會(huì)得到一些DC做STA的一些報(bào)告,每一條路的時(shí)序路徑的延時(shí)之類的,從某個(gè)端口到某個(gè)端口之間的延時(shí),分析整個(gè)電路的最大延時(shí)。
????????在報(bào)告的底部會(huì)有一個(gè)slack,就是時(shí)間裕量,如何判斷時(shí)序是否滿足要求就看這個(gè)slack是否為正,如果為正那就是滿足要求(顯示MET),如果為負(fù)那就是不滿足要求(VIOLATE 違例),即時(shí)間裕量不夠。
????????輸出約束文件:write_sdc my_design.sdc
????????輸出ddc,就是約束文件和綜合后得到的網(wǎng)表:write -f ddc -hier -output my_ddc.ddc
????????write -f verilog -hier -output my_design.gv 輸出門(mén)級(jí)設(shè)計(jì)文件,一般還要輸出 sdf 時(shí)延文件,然后用這兩個(gè)文件去做后仿真。

????????Design Compiler可以使用界面模式也可以使用腳本模式,可以在terminal界面輸入:design_vision打開(kāi)界面化的DC,也可以輸入dc_shell使用腳本模式的DC。


????????OK,上面簡(jiǎn)單的講了一些使用DC的前置知識(shí),下面來(lái)結(jié)合一個(gè)例子實(shí)操一下,拿到一個(gè).v文件之后,怎么使用DC做綜合,然后得出我們想要的timing、area報(bào)告、sdf 時(shí)延文件、網(wǎng)表文件等一系列流程。
????????第一步,寫(xiě)好一個(gè)需要做綜合的RTL代碼,這里up用的是一個(gè)全加器RTL,如下圖:

????????
????????然后創(chuàng)建一個(gè)library文件夾,把?/opt/Foundary_Library/TSMC90/aci/sc-x/synopsis?里的.db文件全部copy到新建的library中,這些文件都是工藝庫(kù)文件,后續(xù)DC設(shè)置需要使用這些東西。

復(fù)制完之后,文件夾如上所示。
此時(shí),library的上一級(jí)文件夾是這樣的:

?接著啟動(dòng)DC:在terminal界面輸入dc_shell啟動(dòng)DC:

????????輸入set_app_var -search_path ./library ,把DC讀取工藝庫(kù)的路徑設(shè)置到我們當(dāng)前目錄的library下,設(shè)置完路徑后還需要設(shè)置target library 和link library;繼續(xù)在terminal中輸入set_app_var target_library typical.db 設(shè)置好目標(biāo)庫(kù),繼續(xù)set_app_var link_library typical.db
輸入完后,dc_shell的界面如下所示:

????????使用的工藝庫(kù)都設(shè)置完了,下面就需要把我們之前寫(xiě)好的RTL code導(dǎo)入到DC中,輸入:read_file -format verilog {/opt/bilibili_DC_pra/full_adder.v} 把全加器RTL文件讀入進(jìn)來(lái),因?yàn)槁窂蕉疾灰粯?,所以大家可以改成自己的路徑再讀取,如果讀取還出錯(cuò),那就在dc_shell中輸入start gui,這個(gè)意思是啟動(dòng)界面化操作,然后在界面化的左上角導(dǎo)入RTL文件即可。
導(dǎo)入成功之后,DC顯示如下信息,包含輸出信號(hào)的類型和位寬:

為了驗(yàn)證我們目前的讀入代碼是否成功,在dc_shell中輸入:check_design來(lái)檢查設(shè)計(jì):

如果和上圖顯示的一樣,顯示1,那就代表沒(méi)有錯(cuò)誤。
????????沒(méi)有錯(cuò)誤就可以給設(shè)計(jì)下約束了,新建一個(gè)時(shí)鐘,在dc_shell中輸入:
create_clock -period 10?[get_ports clk] 和前面基礎(chǔ)部分解釋的一樣,創(chuàng)建一個(gè)周期為10的時(shí)鐘,連接著clk端口。
????????給輸入的引腳設(shè)置相關(guān)的輸入延時(shí),比如說(shuō)給除了時(shí)鐘以外的所有引腳都設(shè)置input_delay為3,并且輸入的input_delay是相對(duì)于clk而言的:
????????set_input_delay -max 3 -clock clk [remove_from_collection [all_inputs] clk]

在DC中顯示1,表示沒(méi)問(wèn)題。
接著設(shè)置輸出的output_delay,比如設(shè)置輸出的最大output_delay為2.5:
????????set_output_delay -max 2.5 -clock clk [all_outputs]
接著設(shè)置所有輸入信號(hào)的翻轉(zhuǎn)時(shí)間:set_input_transition 0.15 [all_inputs]
好,這樣我們約束寫(xiě)完了,再check_design一下確認(rèn)沒(méi)有問(wèn)題。

????????顯示1,沒(méi)有問(wèn)題后,我們就可以開(kāi)始跑綜合了:直接在dc_shell中輸入compile

DC就幫我們跑綜合,并輸出一些報(bào)告了,最后顯示優(yōu)化完成:

????????綜合完之后我們就能讓它report一些我們想要看到的東西,比如一開(kāi)始我們create了一個(gè)10ns為周期的時(shí)鐘,我們可以輸入:report_clock 來(lái)看到我們當(dāng)時(shí)設(shè)定的時(shí)鐘:

????????接著看我們想看的時(shí)序報(bào)告,看在我們?cè)O(shè)置的這些時(shí)序約束下,整個(gè)設(shè)計(jì)是否會(huì)出現(xiàn)時(shí)序違例,輸入:report_timing:

????????可以看到,時(shí)間裕量還有很多,slack顯示MET,表示滿足要求,如果不滿足的話,會(huì)顯示VIOLATE違例。
????????除了timing報(bào)告外,我們可能還會(huì)看面積,輸入:report_area可以查看綜合后的面積報(bào)告

? ? ? ? 在面積報(bào)告里面沒(méi)有線網(wǎng)所消耗的面積,這是因?yàn)槲覀冎皼](méi)有規(guī)定綜合使用的線網(wǎng)模型,如果我們?cè)O(shè)置了wire_load那么最后的area報(bào)告里面也會(huì)有布線所花的面積。
????????另外的,如果我們要把我們?cè)赿c_shell中輸入的那些約束信息,全部打印出來(lái),生成一個(gè).sdc結(jié)尾的時(shí)序約束文件,可以在dc_shell中輸入:write_sdc full_adder.sdc


輸出成功后,可以看到文件夾里面多出了一個(gè)sdc文件,以及可以看到sdc文件中就是我們寫(xiě)的那些約束:

????????同理,我們也可以輸出用于做后仿的.sdf時(shí)延文件:write_sdf full_adder.sdf,而要跑后仿的話,除了時(shí)延文件,還要RTL的網(wǎng)表文件,所以我們?cè)佥敵鯮TL的網(wǎng)表文件:write_file -format verilog -output full_adder_netlist.v

看網(wǎng)表文件可以發(fā)現(xiàn),RTL代碼已經(jīng)都變成門(mén)級(jí)的東西了。

設(shè)計(jì)人員在和后端的做交互的時(shí)候,就交付給他們時(shí)延文件sdf文件和RTL的網(wǎng)表文件即可。
如果在綜合的時(shí)候時(shí)序違例了,該怎么看critical_path呢,為了測(cè)試違例情況,我們把時(shí)鐘周期設(shè)置成2ns,故意讓它違例:create_clock -period 2 [get_ports clk]
修改時(shí)鐘后,再compile一次,compile完report_timing。

我們可以看到,當(dāng)把時(shí)鐘周期設(shè)置為2ns的時(shí)候,出現(xiàn)了時(shí)序違例,時(shí)間裕量那邊也顯示了VIOLATED

????????在timing報(bào)告里面,就直接顯示了關(guān)鍵路徑的走勢(shì),可以看到data_require是1.93ns,但是data_arrival time 卻為-3.38ns,出現(xiàn)時(shí)序違例。

????????好,從0到看報(bào)告的DC綜合教程到這里就結(jié)束了,up簡(jiǎn)單講幾句話:對(duì)于初學(xué)者來(lái)說(shuō),一下子接觸那么多命令肯定是措手不及的,感覺(jué)那么多東西怎么可能記得住,我想說(shuō)的是,雖然命令很多,但其實(shí)用的很多的就是我列舉的那么些,剛開(kāi)始接觸可能一下子記不得,但是用多了,就很熟練打出來(lái)了。就好比linux操作系統(tǒng),“cd ..”是返回到上一個(gè)文件夾,pwd是查看當(dāng)前路徑,rm是刪除,cp是復(fù)制。mkdir是創(chuàng)建文件夾,ls是查看當(dāng)前文件夾內(nèi)容,你看,我說(shuō)了那么多命令,你大概率每一個(gè)都很熟悉,因?yàn)樵谑褂胠inux操作系統(tǒng)的時(shí)候,這些命令太常見(jiàn)了,而DC里面無(wú)論是設(shè)置路徑也好,設(shè)置目標(biāo)工藝庫(kù)也好,下時(shí)序約束也好,用到的命令也就那些東西,一開(kāi)始迷迷糊糊沒(méi)事,你就記住,多練多coding,自然就熟悉了。
????????最后,我是不吃蔥的酸菜魚(yú),秋招在即,祝大家能找個(gè)好工作。