網(wǎng)絡(luò)課程《數(shù)字集成電路靜態(tài)時(shí)序分析基礎(chǔ)》的筆記
地址:https://www.iccollege.cn/portal/courseDetail/193.mooc
TCL 的應(yīng)用
?
Synopsys Tcl
例如,統(tǒng)計(jì)時(shí)鐘數(shù)量,人數(shù)顯然不合理,可以用腳本語言統(tǒng)計(jì),但是可以更加簡單,直接用 Synopsys Tcl 的拓展命令更加便捷
參考資料
?
TCL 在 EDA 工具中的拓展與應(yīng)用
通過對(duì) Design Object 的分析,了解和學(xué)習(xí) DC 獲取電路并進(jìn)行解析的方法
?
常見指令
get_ports
語法格式:get_ports portsName
指令功能:返回 design 中對(duì)應(yīng)的 port object
如何查看 deign 當(dāng)中有沒有一個(gè)叫做 CLK 的 port?
get_ports CLK
{CLK}
- 如何查看 deign 當(dāng)中有沒有一個(gè) port 叫做 SPI?
get—_ports SPI
No object Found!
- 查看 design 當(dāng)中所有的 port(*可以統(tǒng)配任何字符)
get_port *
{A B C D CLK OUT[0] OUT[1]}
- 假設(shè) port 名字交{CLKA CLKB OUTA OUT B INA INB},如何得到所有 C 開頭的 port?
get_ports C*
{CLKA CLKB}
?
get_cells
- 語法格式:get_cells cellsName 指令功能:返回 design 中對(duì)應(yīng)的 cell 的 instance name object
- 查看是否有一個(gè)叫 U4 的 cell
get_cells U4
{U4}
- 查看所有 cell
get_cells *
{U1 U2 U3 U4}
- 查看以 3 結(jié)尾的 cells
get_cells *3
{U3}
?
get_nets
- 語法格式 :get_nets netsName 指令功能:返回 design 中 net 的 object
- 查看 INV 開頭的 net
get_nets INV*
{INV0 INV1}
- 查看所有 net
get_nets *
{A B C D CLK BUS0 BUS1 INV0 INV1 OUT[0 OUT[1]]}
- 查看有多少個(gè) net
llength [get_object_name [get_nets *]]
11
sizeof_collection [get_nets *]
11
?
get_pins
語法格式:get_pin pinsName
指令功能:返回 design 中 pin 的 object
查看叫 Z 的 pin
get_pins */Z
{INV0/Z INV1/Z}
- 查看 Q 開頭的 pin
get_pins */Q*
{ENCODER/Q0 ENCODER/Q1 REGFILE/Q[1] REGFILE/Q[0]}
?
數(shù)據(jù)類型
數(shù)據(jù)類型:”object(對(duì)象)“及其“屬性”
說明:
- object 使 tcl 的一個(gè)重要拓展常見對(duì)象有四種 cell、net、port、pin 每種 object 有他的屬性任何一個(gè)屬性都可以用 get_attribute 得到 list_attribute -class *可以得到 object 的屬性部分屬性可以用 set_attribute 來設(shè)置
Cell object
- 屬性 ref_name:用來保存器 map 到 reference cell 名稱
get_attribute[get_cell -h U3] ref_name
{INV}
Pin object
- 屬性 owner_net:用來保存與之相連的 net 的名稱
get_attribute [get_pins U2/A] owner_net
{BUS0}
Port object
- 屬性 direction:用來保存 port 方向
get_attribute [get_ports A] direction
{in}
get_attribute [get_ports OUT[1]] direction
{out}
Net object
- 屬性 full_name:用來保存 net 的名稱
get_attribute [gets_nets INV0]
{INV0}
get_object_name [get_nets INV0]
{INV0}
get_attribute INV0 full_name
Error:No attribute found
理解屬性以后,就可以完成更多的任務(wù):
- get_* -f:-f 這個(gè) option 可以用來過濾屬性,以得到我們想要的 object 得到所有方向是 input 的 port
get_ports * -f "direction==in"
{A B C D CLK}
- 得到所有方向是 output 的 pin
get_pins * -f "direction==out"
{U1/Q0 U1/Q1 U2/Z U3/Z REGFILE/Q[0] REGFIEL/Q[1]}
- 得到所有 ref_name 是 INV 的 cell
get_cells * -f "ref_name==INV"
{U2 U3}
- 如何的得到電路中所有的 inverter,那么應(yīng)該輸入什么樣的腳本?
1. 直接使用 Synopsys TCL 指令
get_buffers -inverter
2. 人工拓展 TCL 指令
get_inverters
?
使用 TCL 語言控制設(shè)計(jì) EDA 工具
講述一個(gè)簡單的、入門級(jí)的 Synopsys DesignComplier 自動(dòng)化方案,供初學(xué)者參考,感興趣的同學(xué)可以對(duì)該方案進(jìn)行優(yōu)化升級(jí)
特點(diǎn)
- 全自動(dòng)化普適性與可重用性,修改參數(shù)即可應(yīng)用到不同設(shè)計(jì)中
自動(dòng)化電路綜合平臺(tái)只需要用戶將待綜合的設(shè)計(jì)與庫文件放入一個(gè)文件加,修改與帶綜合設(shè)計(jì)對(duì)象有關(guān)的環(huán)境變量參數(shù),在命令窗喚醒 DC 的指令,即自動(dòng)化地完成綜合過程,并得到綜合后的網(wǎng)表文件和所需報(bào)告
運(yùn)行流程:
- 運(yùn)行 run.csh 腳本,啟動(dòng) DC
#!/bin/csh -f
# 清除之前的文檔
rm -rf *.log *svf alib* reports log work
# 新建文件夾
mkdir reports work
# 啟動(dòng) DC 并運(yùn)行 top.tcl
dc_shell-xg-t -32bit -f ./top.tcl
- 建立 reports 與 work 兩個(gè)文件夾。reports 文件夾存放報(bào)告,work 存放文檔和腳本啟動(dòng)頂層腳本 top.tcltop.tcl 按先后順序啟動(dòng)子腳本,最總生成 script.tclDC 讀取 script.tcl 中的約束,最總完成綜合,并將所有報(bào)告寫入 reports 文件夾中
top.tcl 腳本運(yùn)行機(jī)制:
- set_library.tcl:生成設(shè)定庫文件中的 search path 的約束 read_design.tcl:生成讀入設(shè)計(jì)文件的約束 create_clock.tcl:生成時(shí)鐘源相關(guān)的約束 set_rst.tcl:生成復(fù)位端口的約束 set_io.tcl:生成輸入輸出端口的約束 set_cons.tcl:生成保存門級(jí)網(wǎng)表、各種 reports 文件的約束
注意:
- 以上所有約束都自動(dòng)生成,無需人為干預(yù)庫文件、代碼、時(shí)鐘、復(fù)位、輸入輸出等均根據(jù)代碼自動(dòng)進(jìn)行匹配,并生成相應(yīng)的約束最終所有約束都被寫入到 script.tcl 中,供 DC 讀取,完成最終的邏輯綜合過程
?
代碼讀入約束生成
工作流程:
- 設(shè)計(jì)文件通常使用 verilog 文件,所以拓展名通常為 v,所以先將變量 extension 設(shè)為 v 調(diào)用 filelist.tcl 腳本,將所有拓展名為 v 的文件的文件路徑輸出到一個(gè)名為 v_list 的文檔打開 v_list 文檔,根據(jù)文件的內(nèi)容讀入設(shè)計(jì)文件的指令輸出道道 script.tcl 腳本
?
set extension v
source[file join $::script_path test/filelist.tcl]
#調(diào)用 filelist.tcl 腳本
set des[open[file join $::script_path test/work/v—list]r]
set design [gets $des] #打開 vlist 文檔
for{}{$design!=""}{set design [gets $des]}{
puts $script [format "read_file -format verilog %s"$deslgn]
#輸出讀入設(shè)計(jì)文件指令
}
puts $scnpt[format "current_design %s" $top]
#輸出設(shè)置頂層設(shè)計(jì)指令
?
代碼 filelist 生成模塊 filelist.tcl
功能:便利目標(biāo)文件下所有文件,并將拓展名(.v)符合要求的文件完成路徑輸出到指定的文檔,最終形成 DC 讀取 verilog 代碼的約束,寫入 script.tcl 中
工作流程:
- 將工作路徑切換到指定的工作路徑判斷當(dāng)前目錄下的文件拓展名是否與設(shè)置的變量 extension 一直,如果一致,就將該文件路徑輸出到指定的文件如果有文件夾,則遞歸調(diào)用本程序,直至結(jié)束
?
proc FindFile{myDirresult}{
if([catch {cd $WDir} err]}{
puts $result $err
return}
foreach myfile [glob-nocomplam *]{
cd $myDir #切換到對(duì)應(yīng)路徑
if{[string equal $myfile ""]}{
return} #如果是空文件夾就返回
set fullfile [file join $myDir $myfile]
if{[file isdirectory $myfile]}{
FindFile $fullfile $result #如果有下一級(jí)路徑則遞歸調(diào)用本函數(shù)
}elseif{[string equal [file extension $fullfile] [format ".%s" $::extension]]){#判斷擴(kuò)展名是否與要求一致
puts $result $fullfile}}}
?
時(shí)鐘約束生成子模塊
功能和流程:
- 首先調(diào)用 parameter.tcl 腳本,讀取其中用戶對(duì)時(shí)鐘源指定的參數(shù),如時(shí)鐘周期 等;調(diào)用 find_clk.tcl 腳本,該腳本會(huì)將搜索頂層設(shè)計(jì)中的所有的 clk 端口,并將所有搜索結(jié)果輸出到一個(gè)名為 clk_list 的文檔;打開 clk_list 檔,將對(duì)時(shí)鐘端口施加約束的指令輸出到 script.tcl 腳本。
source [file join $::script_path test/findclk.tcl]
#調(diào)用 find_clk.tcl 腳本
set a [open [file join $::script_path test/work/clk_list] r]
#打開 v_list 文檔
set b [gets $a]
set result [open[file join $::script_path test/work/script.tcl]
#DC 時(shí)鐘約束
for {} {$b!=""}{set b [gets $a]}{
puts $result [format "create_clock -name "clock" -period %u -waveform {0 %d}{ %s }" $::clk_source[expr $::clk_source/2]$b]
#將生成時(shí)鐘源的指令輸出到 scnpt.tcl 腳本
puts $result [format "set_dont_touch_network [get_ports%s]"$b]
#對(duì)時(shí)鐘網(wǎng)絡(luò)設(shè)置 don't touch
puts $result [format "set_drive 0 [get_ports%s]"$b]
#設(shè)置時(shí)鐘端口驅(qū)動(dòng)為無窮大
puts $result [format "set_ideal_network [get_ports%s]"$b]
#設(shè)置時(shí)鐘端為理想網(wǎng)線
}
close $result
?
匹配時(shí)鐘端口子模塊
功能:搜索代碼中所有的時(shí)鐘端口,將結(jié)果輸出到 work 文件夾下的 clk_list 文檔
工作流程
- 打開 v-list 文檔,在其中找到頂層設(shè)計(jì)的路徑,并打開設(shè)計(jì)文件;利正則表達(dá)式匹配其中的 clk 端口,并將匹配到的時(shí)鐘端口的端口名輸出到 work 文件夾下的 clk_list 文檔
?
for {} {[eof $designfile]==0}{set fdesign [gets $designfile]}{
if{[regexp{input.*} $fdesign a]}{
#利用正則表達(dá)式匹配到聲明輸入端口那一行
if{[regexp {[^,( ]*clk[^,;]*}$a rport]}{
#利用正則表達(dá)式在那一行匹配后綴為 clk 的端口
puts $fport $rport
#將匹配到的端囗名輸出到 clk_list 文檔
}
}
}
- 其余腳本工作機(jī)制類似。最終,所有的約束都被寫入了 script.tcl 中。script.tcl 腳本完全由自動(dòng)化電路綜合平臺(tái)生成,并非人工編寫;在自動(dòng)化電路綜合平臺(tái)運(yùn)行后,由頂層腳本調(diào)用各子模塊腳本生成該腳本。生成該腳本后,由頂層腳本調(diào)用該腳本,由此實(shí)現(xiàn)對(duì)設(shè)計(jì)的綜合。子模塊腳本生成該腳本。生成該腳本后,由頂層腳本調(diào)用該腳本,由此實(shí)現(xiàn)對(duì)設(shè)計(jì)的綜合。