前言
2023.6.25
2023.6.27 和之前學(xué)的芯動力mooc中很多內(nèi)容相似,這篇整理的邏輯更好些
一、綜合綜述
1、綜合
將RTL代碼轉(zhuǎn)換到基于工藝庫的門級網(wǎng)表。一般分為如下三個步驟。
2、綜合的不同層次
(1)邏輯級綜合
設(shè)計被描述成布爾等式的形式,觸發(fā)器、鎖存器這樣的基本單元采用元件例化(instantiate)的方式表達出來,下面是一個加法器的代碼。
(2)RTL級綜合
電路的數(shù)學(xué)運算和行為功能分別通過HDL語言特定的運算符和行為結(jié)構(gòu)描述出來。電路在每個時鐘邊沿的行為都被確切的描述出來。
(3)行為級綜合
電路的行為可以描述成一個時序程序(sequential program),沒有明確規(guī)定電路的時鐘周期,綜合工具的任務(wù)就是根據(jù)指定的設(shè)計約束,找出哪些運算可以在哪個時鐘周期內(nèi)完成,需要在多個周期內(nèi)用到的變量值需要通過寄存器寄存起來。
二、verilog語言結(jié)構(gòu)到門級的映射
1、always
語句描述的組合邏輯電路,敏感列表要包含所有的輸入變量。
2、if
或case
語句不完整會綜合出鎖存器,解決方法:在最開始的時候給變量賦初值或者把語句寫完整(寫default)。
3、如果設(shè)計者知道case語句不會有其他值,且不想綜合出鎖存器,可以使用一條綜合指令:synopsys full_case
,這句話以注釋的形式加在設(shè)計代碼里面。
帶來的問題:降低代碼的可移植性,會讓他依賴于綜合工具;產(chǎn)生的網(wǎng)表和當(dāng)初的verilog建模有區(qū)別,帶來驗證的復(fù)雜性。
4、casex
語句是有優(yōu)先級的(如優(yōu)先編碼器),相當(dāng)于if-else if-else,如果想要產(chǎn)生互斥的語句,也就是平行結(jié)構(gòu),可以加上synopsys parallel_case
。
5、常見的循環(huán)語句有4種:for
、forever
、while
、repeat
。循環(huán)語句綜合時相當(dāng)于展開循環(huán)體,把相同的電路結(jié)構(gòu)重復(fù)多次,會造成綜合后的面積和性能受到影響。
6、DesignWare
是集成在DC綜合環(huán)境中的可重用電路的集合,DesignWare 分為 DesignWare Basic
與 DesignWare Foundation
,DesignWare Basic 提供基本的電路,DesignWare Foundation 提供性能較高的電路結(jié)構(gòu)。針對同一種算術(shù)符,可以有不同的算法,根據(jù)添加的約束條件來選擇。
在使用的時候,需要有l(wèi)icense,同時在綜合的時候要設(shè)置synthetic library
。
三、使用DC進行綜合
lib格式
:用戶可讀,其中包含信息有工藝條件、單位、基本單元的引腳、方向、時序信息等。db格式
:供DC軟件讀取的格式
1、定義
流程:準(zhǔn)備設(shè)計文件、指定庫文件、讀入設(shè)計、定義設(shè)計環(huán)境、設(shè)置約束、編譯(選擇編譯策略)、報告、存儲數(shù)據(jù)
工藝庫(technology library):目標(biāo)庫和鏈接庫統(tǒng)稱為工藝庫,一般只要設(shè)置好這兩個
set
: 自己自定義的一些變量,方便定義系統(tǒng)變量,相當(dāng)于減少一些重復(fù)的代碼,同時增加了代碼的可讀性,和tcl的語法是一樣的。
set_app_var
:定義DC內(nèi)部的系統(tǒng)變量、指定DC內(nèi)部的連接等。主要指定有:search_path、synthetic_library、target_library、link_library、symbol_library 以及其他的一些命令開關(guān)等。
define_design_lib work -path $WORK_PATH
:DC內(nèi)部命令格式,指定設(shè)計和庫的工作路徑。
printvar target_library
:啟動DC后,可以通過該命令來查看庫的名稱。
dcprocheck xxx.tcl
:檢查該文件的語法是否正確。
source
:是用來定義一些命名規(guī)則,去掉網(wǎng)表中的一些符號,防止后端工程師拿到的網(wǎng)表中帶一些奇怪的符號從而引起不必要的錯誤。(沒有用這個)
source -v -e ./../../../xxxxx/syn/work/hs_name_rules.tcl
在和物理庫相關(guān)的時候需要使用拓?fù)淠J絹韱觗c,選項為-topo
,同時可以把啟動dc時的相關(guān)信息輸出到log文件,指令為tee -i
,中間的|
為管道連接符,連接輸入和輸出
dc_shell -topo | tee -i start_report.log
2、寫時序約束
模塊如下所示:
設(shè)計約束規(guī)格書如下所示:
create_clock -period 3 [get_ports clk]
set_clock_latency -source -max 0.7 [get_clocks clk] //時鐘延遲中的時鐘源延遲的最大值為0.7ns
set_clock_latency -max 0.3 [get_clocks clk] //時鐘網(wǎng)絡(luò)延遲的最大值
set_clock_uncertainty -setup 0.15 [get_clocks clk] //0.15=0.03+0.03+0.04+0.05,兩個時鐘之間的最大延時偏差為0.06,再加上該時鐘的時鐘抖動0.04,同時加上留的裕量0.05
set_clock_transition 0.12 [get_clocks clk]
//輸入延遲時間是相對于clock的相對時間,而這里給出的是絕對時間,所以要減去時鐘延遲,1.4-0.7-0.3=0.4(每臺明白)
set_input_delay -max 0.4 -clock clk [get_ports sel]
//3-2.2-0.2-0.15=0.45,這里只給出了內(nèi)部的組合邏輯延時,如果要知道外部的輸入延時的話,用一個時鐘周期去-組合邏輯延時-Tsetup-uncertainty
set_input_delay -max 0.45 -clock clk [get_ports data*]
set_output_delay -max 0.5 -clock clk [get_ports out1] //0.42+0.08
set_output_delay -max 2.04 -clock clk [get_ports out2] //3-0.81-0.15=2.04
set_output_delay -max 0.4 -clock clk [get_ports out3]
3-0.15-輸入延時-2.45=輸出延時
輸入延時+輸出延時=0.4 只要滿足這個要求即可,可以根據(jù)后端要求再進行調(diào)整
set_input_delay -max 0.1 -clock clk [get_ports Cin*]
set_output_delay -max 0.3 -clock clk [get_ports Cout]
3、寫環(huán)境約束
(1)設(shè)置環(huán)境條件
一般不設(shè)置的話默認(rèn)用庫里面默認(rèn)的norminal
set_operating_conditions -max $OPERA_CONDITION -max_library $LIB_NAME
(2)設(shè)置連線負(fù)載模型
在計算時序路徑的延遲,需要知道門單元延遲
和連線的延遲
。
門單元的延遲采樣非線性延遲模型,依據(jù)輸入轉(zhuǎn)換時間和輸出負(fù)載的查找表得出,
同時查找出輸出轉(zhuǎn)換時間,作為下一級電路的輸入轉(zhuǎn)換時間。
連線的延遲通過線負(fù)載模型進行估算,根據(jù)連線的扇出來估算連線的寄生參數(shù)RC。
線負(fù)載模型(右側(cè))給出的是單位連線的電阻/電容/面積信息。
下面的計算超出了最大扇出長度,根據(jù)slope來外推計算。
set auto_wire_load_selection false //DC可以自動選擇合適的連線負(fù)載模型,可以使用命令關(guān)掉
set_wire_load_model -name $WIRE_LOAD_MODEL -library $LIB_NAME
連線負(fù)載模型的模式:圍繞(enclosed)、頂層(top)、分段(segmented)enclosed模式
:使用的是包圍該模塊的連線負(fù)載模型。top模式
:最悲觀的情況,使用的是頂層的連線負(fù)載模型。segmented模式
: 位于兩個小模塊中的部分采用這兩個小模塊對應(yīng)的連線負(fù)載模型, 中間部分采用子模塊的連線負(fù)載模型。也就是連線位于哪個模塊就采樣哪個模塊的模型。
set_wire_load_mode enclosed/top/segmented
(3)設(shè)置驅(qū)動強度
默認(rèn)情況下會認(rèn)為輸入轉(zhuǎn)換時間為0,為了得到真實的延遲,我們需要給輸入端加上驅(qū)動
set_drive 0/100 //0表示最大驅(qū)動強度,通常為時鐘端口,其他數(shù)字的單位為電阻
set_driving_cell -lib_cell FD1 -pin Q [get_potrs IN1] //指定一個真實的外部單元來進行驅(qū)動,指定cell和cell的哪個引腳來進行驅(qū)動,不指定引腳的話也會有個默認(rèn)引腳
set_input_transition 10 [get_ports IN1] //也可以直接指定某個輸入端的轉(zhuǎn)換時間
(4)設(shè)置電容負(fù)載
同理,默認(rèn)情況下外部端口電容負(fù)載為0
set_load 5 [get_potrs IN1] //直接設(shè)置為某個具體的值
set_load load_of cell/lib/pin [get_ports out1] //設(shè)置為某個特定單元的引腳,一般為輸入端口
set_load [expr [load_of my_lib/inv1a0/A]*3] out1 //相當(dāng)于設(shè)置輸出端同時連接3個反相器
和輸入輸出延遲一樣,一般不知道每個模塊輸入端口的外部驅(qū)動單元和/或輸出端口的外部輸出負(fù)載,可以假設(shè)輸入端口為驅(qū)動能力弱的單元驅(qū)動(即轉(zhuǎn)換時間長),同時限制每一個輸入端口的輸入電容(負(fù)載),限制輸出端口的驅(qū)動模塊數(shù)目。
(5)設(shè)置設(shè)計規(guī)則約束(DRC)
一般設(shè)計規(guī)則約束的優(yōu)先級最高,其中優(yōu)先級依次為最大電容
、最大轉(zhuǎn)換時間
、最大扇出
。
設(shè)置約束如下:
set DRIVE_PIN TECH_LIB/invla27/Y //設(shè)置某個單元的輸出引腳為外部驅(qū)動單元
set MAX_CAP [get_attribute $DRIVE_PIN max_capacitance] //得到最大電容值
set CONSERVATIVE_ MAX_CAP [expr $MAX_CAP / 2.0] //除以一半,留點裕量
set_max_capacitance $CONSERVATIVE_MAX_CAP [get_ports IN1] //設(shè)置最大電容值
set_max_capacitance 3.0 $current_design //為整個設(shè)計添加最大電容約束
set_ max_transition $CONSERVATIVE_MAX_TRANS [get_ports IN1]
set_max_fanout 6 [get_ports IN1] //這里設(shè)置的是最大扇出負(fù)載,并不是扇出的絕對數(shù)目
get_attribute TECH_LIB/invla1/A fanout_load //0.6,用來查看load,根據(jù)上面可以得出6/0.6=10,u也就是可以驅(qū)動10個這樣的單元
(6)面積約束
面積的衡量單位有三種:2輸入與非門(2-input-NAND-gate)、晶體管數(shù)目(Transistors)、平方微米(Square microns),可以通過report_area
這個指令來判斷面積的單位,輸出為1第一種,輸出為4第二種,輸出為其他第三種。
不設(shè)置面積約束的情況下,DC也會對其進行面積優(yōu)化,設(shè)置為0的話會進行最大限度的優(yōu)化,直至不能再繼續(xù)優(yōu)化了。對于較小的設(shè)計,可以設(shè)置面積約束為0,但是對于較大的設(shè)計,這樣會消耗很多的時間。
set_max_area 0
(7)完整的環(huán)境約束
set LIB_NAME slow //最差勁的情況
set WIRE_LOAD_MODEL tsmc090_w150
set DRIVE_CELL INVX1 //驅(qū)動單元選的是庫中的反相器
set DRIVE_PIN Y
set OPERA_CONDITION slow
set ALL_IN_EXCEPT_CLK [remove_from_collection [all_inputs] [get_ports "$CLK_NAME"]] //從all_inputs這個對象集合中,移除掉CLK_NAME這些代表的端口
set MAX_LOAD [expr [load_of $LIB_NAME/INVX8/A]*10]
set_operating_conditions -max $OPERA_CONDITION -max_library $LIB_NAME
set auto_wire_load_selection false
set_wire_load_mode top
set_wire_load_model -name $WIRE_LOAD_MODEL -library $LIB_NAME
set_driving_cell -lib_cell ${DRIVE_CELL} -pin ${DRIVE_PIN} $ALL_IN_EXCEPT_CLK
set_load [expr $MAX_LOAD * 3] [all_outputs]
四、輸出結(jié)果
綜合之后把門級網(wǎng)表和約束交付給后端,進行布局布線和時鐘樹綜合等流程。
如果時序違例大于時鐘周期的25%
,需要重新修改RTL代碼。
時序違例在10-25%
之間,可以進行優(yōu)化,如利用指令compile_ultra
,在拓?fù)淠J较逻M行編譯,適合于高性能的電路優(yōu)化。
//設(shè)置搜索路徑和工藝庫
set search_path "../lib/logic ../src" #設(shè)置搜索路徑
set target_library " slow.db " #設(shè)置標(biāo)準(zhǔn)元件庫
set link_library "* $target_library "
set symbol_library " smic18.sdb " #設(shè)置標(biāo)準(zhǔn)元件圖標(biāo)庫
set access_internal_pins true
set report_path "./reports" #設(shè)置reports文件夾
set output_path "./outputs" #設(shè)置outputs文件夾
//讀入設(shè)計文件
read_file -format verilog cic_filter.v #讀取verilog設(shè)計文件
read_file -format verilog divider64.v
//指定當(dāng)前設(shè)計
current_design cic_filter #指明主程序
link #工藝庫鏈接
uniquify
set design_name [get_object_name [current_design]]
//設(shè)置環(huán)境約束,包括線負(fù)載模型
set_wire_load_model -name "smic18_wl10" #設(shè)置線負(fù)載模型
set_wire_load_mode top
//設(shè)置時鐘約束
create_clock -period 156 -waveform {0 78} [get_ports clk] -name clk #設(shè)置時鐘,周期156ns,脈寬0-78ns
create_generated_clock [get_pins div/clk_div] -source [get_ports clk] -divide_by 64 -name clk_div #分頻64后的時鐘
set_clock_latency 2.5 clk #延遲時間2.5ns
set_clock_transition 0.3 clk #翻轉(zhuǎn)時間0.3ns
set_clock_uncertainty 1.5 -setup clk #建立時間1.5ns
set_clock_uncertainty 0.3 -hold clk #保持時間0.3ns
//設(shè)置環(huán)境約束
set_drive 0 [list clk rst_n] #設(shè)置輸入驅(qū)動強度為0
set_driving_cell -lib_cell NAND2X1 in #設(shè)置驅(qū)動單元
set_input_delay 35 -clock [get_clocks clk] {in rst_n} #設(shè)置輸入延時35ns
set_output_delay 35 -clock [get_clocks clk_div] [get_ports out] #設(shè)置輸出延時35ns
set_load 2 [all_outputs] #設(shè)置輸出負(fù)載為2pF
set_max_area 0
//輸出綜合前的時序信息和設(shè)計信息
check_design > $report_path/check_design_before_compile.rpt
check_timing > $report_path/check_timing_before_compile.rpt
//綜合的指令compile
compile
compile -incremental_mapping -map_effort high
//把文件進行保存,DC是不會保存的
write_sdf -version 2.1 $output_path/${design_name}_post_dc.sdf #時序描述
write -f ddc -hier -output $output_path/${design_name}_post_dc.ddc
write -f verilog -hier -output $output_path/${design_name}_post_dc.v #網(wǎng)表
write_sdc $output_path/${design_name}_post_dc.sdc #約束
//報告時序、面積、功耗等相關(guān)信息
report_constraint -all_violators -verbose > $report_path/constraint.rpt
report_qor > $report_path/qor.rpt
report_power > $report_path/power.rpt
report_area > $report_path/area.rpt
report_cell > $report_path/cell.rpt
report_clock > $report_path/clk.rpt
report_hierarchy > $report_path/hierarchy.rpt
report_design > $report_path/design.rpt
report_reference > $report_path/reference.rpt
report_timing > $report_path/timing.rpt
//最后檢測時序、設(shè)計信息
check_design > $report_path/check_design_post_compile.rpt
check_timing > $report_path/check_timing_post_compile.rpt
#start_gui
五、簡答
1、目標(biāo)庫和鏈接庫的區(qū)別
target library
是rtl代碼映射到工藝庫時stdcell所在的庫,link library
是包括了target library,同時還包括了設(shè)計中用到的IP等宏模塊,查找reference進行連接時所搜尋的庫,是為了更好地理解design。
link庫路徑面前加*號表示開辟一塊單獨的內(nèi)存空間給DC自己使用,然后先搜尋內(nèi)存中已有的庫,然后再搜尋變量link_library指定的其他庫。DC搜尋的庫為search_path指定的目錄(比如說之前讀入設(shè)計時讀入了庫a,庫a存到內(nèi)存里;這時DC在進行綜合的時候,發(fā)現(xiàn)缺少某個東西,于是就先從庫a里面找,找不到時就會從列表里面的變量路徑中找)。文章來源:http://www.zghlxwxcb.cn/news/detail-519071.html
一般情況下,我們只用一個工藝庫,需要引用目標(biāo)工藝庫,因此指定target_library
;此外我們還有可能用到synopsys公司的IP核,因此需要指定他的DW庫。文章來源地址http://www.zghlxwxcb.cn/news/detail-519071.html
到了這里,關(guān)于《綜合與Design_Compiler》學(xué)習(xí)筆記——第一章綜合綜述 第二章verilog語言結(jié)構(gòu)到門級的映射 第三章 使用DC進行綜合的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!