Tcl腳本在IC設計中的應用

這是IC君的第11篇原創文章 (同步於 微信公眾號 icstudy)

平時我們了解的編程語言C,C++,Java屬於編譯型語言,它們通常是為了開發專業的軟體或者作為高性能計算之用。那如果我們只要實現一些簡單的功能呢?腳本也許是一個更合適的選擇。腳本語言是為了縮短傳統的編寫-編譯-鏈接-運行過程而創建的計算機編程語言。腳本通常是解釋運行而非編譯,有簡單、易學、易用的特性,目的就是希望使用者能夠快速完成程序的編寫工作。

IC設計中常用的腳本有Tcl、Perl、Shell、Python(最近好像很紅)等,在這些腳本裡面,Tcl的語法最為簡單,最容易上手,所以今天我們先來聊一聊它。

Tcl 是「工具控制語言(Tool Control Language)」的縮寫。Tk 是 Tcl「圖形工具箱」的擴展,它提供各種標準的 GUI 介面項,可以快速的進行高級應用程序開發。

John K. Ousterhout於 1988 年開始開發 Tcl/Tk(讀作「tickle tee-kay」),然後是加州大學伯克利分校的一名教授繼續對它進行開發。Tcl 的設計目標就是可擴展性強、容易上手的。目前大部分EDA工具都支持Tcl語言,如Design Complier、quartus、Synplify、modesim、finesim等。而且Tcl在各個平台都能運行,一般的Linux/Mac OS下面都會安裝tclsh,Windows下面可以安裝官方的ActiveTcl工具,所以大家很容易找到學習的環境。

以IC君的經驗來看,Tcl/Tk在IC領域的主要作用有3個:

1. 複雜的文本處理。Tcl可以把文本中的每一行變為一個列表,最簡單的列表就是包含由任意個空格、製表符、換行符分隔開的任意多個元素的字元串。例如,以下字元串 John anne mary jim就是一個有4個元素的列表。你可以直接根據元素編號來獲取字元串內容,想一想這個特性是不是很方便我們做文本處理,Perl是不支持這個功能的哦。另外就是正則表達式,這個是文本處理的大殺器,Tcl也是完全支持的。所以每當看到有人說Tcl比Perl弱很多,沒什麼好學的,IC君心裡就把他默默的鄙視了一百遍,那是你不會用好不好。IC君的經驗是如果我們在處理文本時用常規的sed/vim處理起來很麻煩,那就寫一個Tcl腳本來解決吧。如果還不行,那就寫兩個Tcl腳本吧。

2. 自動化執行flow。例如自動執行整個綜合的flow,得到最後的結果和report。只要敲一次鍵盤,然後就可以喝著茶等待最終的結果,是不是爽歪歪。

3. 編寫一些強大的EDA工具。之前IC君入職一年後,在項目執行的空閑時間寫了一個能夠基於晶元布局自動生成有寄生RC電路的腳本,大概幾千行的代碼。相比原來的人工flow,這個腳本大概能節省一個星期的工作時間,而且電路模型更精準,現在跟我同組的同事都在使用這個腳本。另外最近IC君發現我司的Tcl大牛寫了一個主程序3萬多行Tcl/Tk代碼的圖形界面自動建模工具。IC君在用這個工具的時候,感覺和使用大型EDA公司的工具沒太大的區別,除了GUI略丑和BUG略多之外

。由於公司不能拍照,這裡也無法向大家展示這個EDA工具。總之,如果你的腦洞足夠大,是完全可以利用Tcl/Tk開發出強大的EDA工具的。

下面我們就通過幾個Tcl腳本的例子,來具體說明一下Tcl的用法。

第1個例子是用來簡化網表的: 主要功能就是將給定subckt 裡面的電路移除掉,但是保留埠定義,網表內容如下圖所示:

#!/usr/bin/tclsh

#判斷輸入變數是不是2個,如果不是2個,提示正確用法

if {$argc!=2} {

puts "Error usage: The correct usage is delsubckt netlist subckt_name"

return 0

}

#獲取網表名

set netlist [lindex $argv 0]

set netlist_temp "$netlist.temp"

#獲取要刪除內容的Subckt名字, 如AMP

set subckt_name [lindex $argv 1]

set subckt_name [string toupper $subckt_name]

#打開網表文件為後面讀取做準備

set nop [open $netlist r]

#打開臨時文件為後面寫入做準備

set ntempop [open $netlist_temp w+]

set flag 0

set lastname ""

#只要沒到文件末尾,就一行行的讀下去

while {[gets $nop line]>=0} {

#獲取一行的第1個元素

set fname [lindex $line 0]

#將這個元素轉換為大寫格式

set fname [string toupper $fname]

#獲取一行的第2個元素

set sname [lindex $line 1]

set sname [string toupper $sname]

#判斷subckt的名字是不是屬於我們要刪除的內容

if {$flag==0&&$fname==".SUBCKT"&&$sname==$subckt_name} {

#如果是我們要找的subckt,先把subckt的定義輸出到臨時文件中

puts $ntempop $line

#設定找到的標誌

set flag 1

#繼續讀取下一行,判斷是不是開頭有+號,如果有+號,表示定義沒結束

gets $nop line

set fname [lindex $line 0]

set fi [string range $fname 0 0]

while {$fi=="+"} {

puts $ntempop $line

gets $nop line

set fname [lindex $line 0]

set fi [string range $fname 0 0]

}

}

#如果不是不是我們要找的subckt,那就直接輸入到臨時文件中去

if {$flag==0} {

puts $ntempop $line

}

#如果找到標誌為1,並且第1個元素為.ENDS, 則輸出到臨時文件中去,整個subckt內容的刪除工作完成

if {$flag==1&&$fname==".ENDS"} {

puts $ntempop $line

set flag 0

}

}

#等文件的所有行都遍歷過後,退出打開的文件句柄

close $nop

close $ntempop

#將臨時文件命名為我們原來的文件

exec mv $netlist_temp $netlist

puts "Generate $netlist successfully!"

這個腳本裡面包含了打開文件的過程,文本處理的過程,一般的文本處理套用這個腳本,改改文本處理的過程就可以實現了。總得來說,Tcl的語法還是蠻順暢的,只要想法清楚,很容易就可以用代碼實現出來。

第2個例子是關於DC綜合腳本的執行flow的:

#//顯示開始時間

sh date

# //移除DC中原有的設計

remove_design –designs

#//下面是庫的設置

set search_path [list /tools/lib/sxx25/feview_s/version1/STD/Synopsys /tools/lib/sxx25/feview_s/version1/STD/Symbol/synopsys]

set target_library { sxx25_tt.db }

set link_library { sxx25_tt.db }

set symbol_library { sxx25.sdb }

#//讀入example1.v文件

read_file -format verilog ~/example1.v

# //把EXAMPLE1指定為當前設計的頂層模塊

current_design EXAMPLE1

#//設置一些IO埠名

set clk [get_ports clk]

#//設置變數clk的值是[get_ports clk],在下面的代碼中若出現$clk字樣,則表示引用該變數的值,即用[get_ports clk]代替$clk。

set rst_n [get_ports rst_n]

set general_inputs [list a b c]

set outputs [get_ports o]

#//設置時鐘約束條件

# //創建一個周期為20ns,占空比為1的時鐘

create_clock -n clock $clk -period 20 -waveform {0 10}

set_dont_touch_network [get_clocks clock]

# //設置時鐘埠的驅動為無窮大

set_drive 0 $clk

# //設置時鐘端為理想網線

set_ideal_network [get_ports clk]

#//設置複位信號約束

set_dont_touch_network $rst_n

set_drive 0 $rst_n

set_ideal_network [get_ports rst_n]

#//設置輸入延時

set_input_delay -clock clock 8 $general_inputs

#//設置輸出延時

set_output_delay -clock clock 8 $outputs

#//設置面積約束和設計約束

set_max_fanout 4 $general_inputs

set_max_transition 0.5 [get_designs "EXAMPLE1"]

set_max_area 0

#//綜合優化

compile -map_effort medium

#//保存文件

# //保存反標文件

write -f db -hier -output ~/EXAMPLE1.db EXAMPLE1 -xg_force_db

write -f verilog -hier -output ~/EXAMPLE1netlist.v EXAMPLE1

write_sdf -version 1.0 ~/EXAMPLE1.sdf

#//產生報告並保存

report_area > EXAMPLE1.area_rpt

# //把報告面積的文件保存成EXAMPLE1.area_rpt文件,運行完腳本以後可以查看該文件。

report_constraint -all_violators > EXAMPLE1.constraint_rpt

report_timing > EXAMPLE1.timing_rpt

# //顯示結束時間

sh date

從上面的綜合腳本來看,一部分語句是Tcl原生格式的,其它的是EDA工具DC支持的語句,不過如果你對Tcl很熟悉的話,上面的代碼閱讀起來就很親切。

第3個例子是TK的,這個例子很簡單,就是寫一個hello world圖形界面:

#!/usr/bin/wish

button .hello -text Hello -command {puts stdout "Hello, World!"}

button .goodbye -text Bye! -command {exit}

pack .hello -padx 60 -pady 5

pack .goodbye -padx 60 -pady 5

代碼執行時在命令行輸入 wish test.tcl,結果如下圖所示,

當你點擊Hello按鈕,命令行會輸出Hello, World,如果點Bye,則程序退出。根據功能大家也可以猜測上面的代碼的意思。如果大家想寫一個強大的圖形端的工具,可以進一步參考Tcl/Tk的書籍。

IC君講的這些腳本例子都是拋磚引玉,大家應該很容易結合自己工作的實際需求寫出強大的腳本。

如果大家想獲取上面例子的源代碼,或者腳本之類的問題想交流一下,以及一些其它的IC問題需要交流,可以加入我們的微信群。

最近IC君深有感觸,有時候你百思不得其解的問題,跟大家交流一下,說不定就能解決哦;有時候你千辛萬苦尋找的東西,也許群友不經意間就能提供哦。

歡迎掃描二維碼進群哦:

aHR0cHM6Ly93ZWl4aW4ucXEuY29tL2cvQWVwYnlJWkxjc01CWTdiZA== (二維碼自動識別)


推薦閱讀:

遊戲編程領域中有哪些鮮為人知的腳本語言,且為什麼它們沒有像lua一樣普及?
如何想學點編譯原理,又不想直接看龍虎之類的書籍,太多理論,乾燥?
目前,網頁腳本語言三個主流:PHP,JSP,.NET。究竟是一種怎麼樣的形勢?是三國鼎立,還是其他的形勢呢?各自的真正優勢,又是在哪裡?
Lua 5.3為何很慢?該不該升級?

TAG:IC设计师 | 芯片设计 | 脚本语言 |