pretty code

2025年3月27日 星期四

這兩天的努力果然還行

從去年到現在,陸續用了不少套 EDA Tool,有 Open Source 的也有商業的。

即使到現在,我還是喜歡地方自治的架構而不是像 ORFS 那般集中管理。

最近開始又重新設計了一套 EDA script 產生器的流程,用文字檔當 config 雖然陽春,但背後的精神卻是不容小覷。

EDA Tool command 一拖拉庫,如果每個都要重新定義,其實會造成目前使用者的困擾。故我盡量讓 config 就是說明書,使用者不需要再讀取另外一份文件才知道如何使用我的 tool,定義好我的 config 規則後,細節都在 config 裡,程式只是框架,要新增別的 EDA Job 也是很容易的!

至少目前我看起來,不論是 Synthesis、Tessent MBIST、Scan Synthesis 都是可以勝任的,之後如果需要擴充,只要秉持一貫的精神即可。

話雖如此,這個 Tool 也花了我昨天下午到今天一整天的時間,直到剛剛才在 VPN 的連線中寫完第一版。

還好我 VIM 還算可以,不然 coding 都不順了XD

我現在大概也到了草木飛花皆可為劍的境界了吧?不再需要 IDE 的輔助,坦白說,就算是我這 20 年最常用的 UltraEdit 也是離 IDE 有段距離!

不過我 Python 確實不行,畢竟我之前很少用,每一個函數我都需要 Google,從來沒背下來過,我大概只有 C 語言函數勉強可以不 Goole,因為 C 語言函數真的不多呀XD

2025年3月25日 星期二

vim function 還真的不好寫

為了查詢某個 Verilog module 的某根訊號,我很常做的一件事就是:

01. 跳到 module 開頭那一行
02. 按下 shift + v 反白該行
03. 按下 /endmodule 執行搜尋的動作並將整個選取範圍擴大到 endmodule 那行
04. 按下 y 複製內容
05. 執行 :tabe xxxx.v 
06. 在新的視窗按下 p 貼上剛才複製內容

原本想用 nnoremap 做掉,但我需要不同的檔名,開新檔時才不會重複。

Google 了好一陣子,終於拼湊出我要的結果,現在只要按下 <leader>module 就可以一氣呵成了!

2025年3月23日 星期日

vim 真的是很神奇的東東

20 年前初探程式語言後,陸續學了不少東西,但已經很少東西會讓我驚艷了。

這一年多來,除了 Verilog 我已經很少用 UltraEdit 寫 code 了,取而代之都是使用 vim。

這個星期為了串 chain,需要在一堆 report 中尋找問題,因為副檔名是 rpt,故 vim 其實不知道要如何顯示語法顏色?

查了一下,只需要用 set syntax=sh 就可以指定使用 script 的語法來顯示內容,搭配快速鍵後更能如虎添翼。

即使已經用了 vim 一年多,不論何時,vim 總是能讓我驚艷。


不過,vim 很像修仙,使用它很講究機緣,機緣不到,也不會想嘗試就是了。

目前對我來說,vim 就像我老婆在追的仙俠劇女主角一樣,稱得上是絕代佳人無誤XD 

2025年3月18日 星期二

人生中第二次被撞

昨天早上開車上班時,停等紅燈時被一台摩托車推撞,當下髒話都快罵出來了XD

不過看在是媽媽的份上,身後又載著一位小朋友,想想就算了,想說修車應該沒多少錢,自己 cover 就好,互留個 LINE 帳號就沒報警了。

但到辦公室寫 code 時,就覺得脖子有一個角度怪怪的,思考良久,還是趕在醫院停止掛號前請假兩小時提早下班檢查。

幸好,醫生覺得是被撞當下可能被嚇到,肌肉有點僵硬,導致韌帶拉傷,照了一堆片子後,開個鬆弛劑,追蹤一星期後續如果沒有怎樣應該就沒事了。

既然都請假了,順便走路去車廠問問後保桿價錢,不問不知道,初估材料加工錢就要噴掉二萬一了,實際報價還要等到星期六回廠吊起車子檢查才能確認最後價錢。


隨便拍了一張照片就已經裂成這樣,其他的我不想拍了,車牌一邊都翹得不成人樣。


唉,錢是小事,但還是覺得很無辜,不過小朋友沒事就好,不然雖然不是我的錯,還是會覺得很阿雜,為人父母的還是要小心騎車。

距離上一次被撞大概也有 10 年多了,同樣不變的是當時車上也是有小朋友,但上一次我自己只要一萬塊就搞定了XD

還是記錄一下正常狀況下車禍應該如何處理?

01. 如果要報警請打 110 報警。
02. 如果像我沒有報警,車上如果有粉筆記得標示四輪位置並拍照。
03. 如果不報警,記得互留資訊避免被說肇事逃逸。
04. 如果要和解可以去警察局,警察局會提供場地及和解書,另外要自行準備聲請撤回告訴狀,避免事後有人反悔又要提告。
05. 調解會更有效力,新北法制局可以線上申請調解,但需要雙方資料。
06. 如果有傷記得要去醫院開立診斷證明,以備不時之需。

雖然花錢,但大家都沒事還是不幸中的大幸,去蘋果基金會以父母名義捐個一萬,希望父母身體健康,無病無痛,過幾天記得再查詢確認基金會是否有入帳。

2025/03/25 更新

昨天進廠吊起確認後,要修的東西更多了,幸好最後大概是三萬五內可以搞定。不過後保桿裡有一支塑膠樑,要待拆卸後才能確定是否要更換,故只先刷三萬元。

自己真的沒有臨機應變能力,既然連底盤都撞到了,保險起見,處在中間的塑膠樑理應一併換掉就好,何必管它是好是壞,當時沒有想到,星期一去追加好了,希望能在保養廠搬家前搞定此事。

晚上回家順便確認了蘋果基金會金額有確定入帳,自從上次在某佛教基金會捐款完全查不到後,我便會養成事後確認的習慣,畢竟,我不想收到捐款收據製造垃圾,難保不肖人士,藉機上下其手,雖然現在查到也不能代表什麼就是了。

2025年3月15日 星期六

grep 待解謎題

為了找出 instance,理論上同樣的 Tcl regex 應該也是可以用在 grep,但結果就是不行?

改用 -P 就可以?

或是拿掉 \] 也可以找出 non escaped identifier?

容我好好想想。


2025/03/15 晚上更新

還不確定為什麼,但知道解決辦法。

此篇文章給了我靈感,] 如果放在第一個字元(不算 ^),可以不需要跳脫符號,如此一來就可以找到那個 escaped identifier cell 了。

目前確定的是 sed 跟 grep 的行為都是一致。


2025/03/16 更新

原來一直都是我在亂用XD

正規表示法我最早學是在 Perl 裡,但只學些皮毛,後來大部分只用 C 後,便很少使用正規表示法。

後來又陸續多學了一些程式語言,直到現在,真的用 Linux 當開發環境,開始大量的使用 grep awk sed 這些好用的工具後,我終於嘗到苦果了XD

這樣也好,趁這個時候把 regex 的一些細節搞清楚。

當我們嘗試用工具或是程式語言來處理正規表示法的時候,第一件事一定要確定該工具或是該程式語言使用的是哪一種正規表示法!

目前比較熱門的大概有 3 派:

POSIX BRE - Basic Regular Expression
POSIX ERE - Extended Regular Expression
PCRE - Perl Compatible Regular Expression

BRE - grep, vi, sed
ERE - awk, egrep

我個人用的比較偏 ERE。

所以我們應該要 follow ERE 的標準。

而我最習慣也最常用的就是 [a-zA-Z0-9] 這樣的描述,在 BRE or ERE 中稱呼這樣的語法為 Bracket Expression

我這裡用 2004 版的 Spec 來描述,英文比較好懂。


從上面我們可以得知:

01. 特殊符號 .*[\,在 Bracket Expression 中不需要 escaped。
02. ] 因為是終止 Bracket Expression 用,有其特殊性,故要 match 它本身時,我們需要將其放在 Bracket Expression 裡的第一個字元,或是在 ^ 後面。

故我應該只要這樣下就可以了,少了跳脫符號,感覺清楚多了。


至於為什麼我在 Bracket Expression 裡面用 escaped  跳脫那些特殊符號也可以,這點我暫時還不知道是在那個 Spec 的條目中可以解釋就是了。

不過重點是,一樣的語法,我在 Tcl 中卻要跳脫,因為 Tcl 用的是一個叫 ARE 的派別,基本上是 ERE 的延伸,我覺得這是用正規表示法最麻煩的地方。

2025年3月13日 星期四

tcl performance

原本我的 netlist_treeview 是要拿來當我的 gui tool 用,後來為了 report 加了一些額外的功能。

當遇到比較多 instance 的 netlist,居然要跑個 5 ~ 6 分鐘,這樣的速度不是很能接受!

於是做了一些修改,記錄一下自己的心得。

01. 減少 function call

原本的功能都是寫成函數,增加不同類別的檢查只要改變參數呼叫原本的 function 即可,為了加速,我把原本的函數複製了 3 份,貼在原本各自呼叫的地方,雖然程式碼很醜,但快了 20 幾秒有。

也減少了一直重複呼叫 array get 或是 array set,因為要將 array 傳進 proc 似乎要先 list 化?沒有直接傳進去的用法。

02. 遞迴函數減少參數傳遞,改用全域變數。

這樣的改動對於加速也是有感的,大概可以再快個幾秒,就不知道是否是雜訊就是了?

03. 減少 lreplace lappend 的呼叫

改完後感覺有時還變慢?不確定是不是為了這個,反而在遞迴中增加參數傳遞導致,但至少目前這個遞迴函數的行數比原本少了一半,看起來舒服多了。

另外,可以透過 override proc 和 trace 來將原本沒有計時的函數呼叫自動增加計時功能,但這樣一來執行速度會變得很慢,我要跑 5 ~ 6 分鐘的 case 根本沒辦法順利 profile 。

下面是網友的範例程式,記得要在程式結束前自己呼叫 TimingProfilerDump。


2025/03/14 更新

果然跟我想的一樣,問題是出在遞迴上,加上下面 command 就可以解決問題。原本要跑 5 ~ 6 分鐘的程式,現在只要 15 秒,感覺合理多了。

interp recursionlimit {} 100000

另外,參考網友 callback 方式,改了一版自己的 monitor 程式,整體來說也比較好懂。

一般來說,遞迴函數一定會帶參數,這樣才能有條件來結束遞迴,我的 monitor 也能支持遞迴記錄。

array set ::debug_state {}
set fd [open "debug.log" w]

proc  monitor {args} {
global debug_state
global fd

set proc [lindex [lindex $args 0] 0]
set index [lindex [lindex $args 0] end]
set type [lindex $args end]

set key "${proc}@${index}"

if {$type == "enter"} {
set debug_state($key) [clock clicks -milliseconds]
} else {
set end [clock clicks -milliseconds]
puts $fd "$key took: [expr {$end - $::debug_state($key)}]"
}
}

rename proc _proc
_proc proc {name arg body} {
_proc $name $arg $body

trace add execution $name enter monitor
trace add execution $name leave monitor
}

proc test {index} {
if {$index >= 5} {
return
}

after 500
puts "in test_${index}"

incr index
test $index
}

test 1

2025/03/14 晚上更新

雖然要跑 5 ~ 6 分鐘的 design 可以透過調整 stack 參數,變成只要 15 秒。但有一個需要跑 99 秒的 design 卻還是要花差不多的時間?

目前只能確定,還是因為多了一個要檢查的 cell 類別,導致在遞迴函數裡,需要多呼叫 4 ~ 5 萬次導致,如果拿掉這個 cell 類別的檢查,就又會回到 10 幾秒的水準。

之前猜測遞迴耗時的原因是因為動態調整 stack size 的緣故,而這個所謂調整的演算法一次增加的幅度應該不多,這才能解釋遇到過多的遞迴呼叫導致時間不合理增加。

改天還是要看看 source code 才能得知。

2025/03/16 更新

我越想越覺得不對?這個參數看起來超過限制就是會報錯,跟我的情況似乎搭不起來?

我開始懷疑我在耍白癡了?我的 netlist_treeview.tcl 會因為要檢查的 cell 類別檔案在不在而決定要不要檢查,感覺是影響我變慢的那一個 cell 類別檔案當時並不在同資料夾內,導致我以為我的更動有效的緣故?

明天去公司的第一件事要來檢查一番。

2025/03/17 更新

果然是我耍白癡,沒有把 sdff.txt 放在同一個資料夾,害我誤以為 recursionlimit 可以解決問題。

不過問題來了,那到底是哪邊有問題?

雖然早上停等紅燈,無故被推撞,導致一整天心緒不寧XD

終於還是在決定下班前請個 2 小時假去醫院做個檢查前找到問題。

在記錄問題前,先記錄一下相關數據。

我這個 netlist 裡面的 instance 大概有 111 萬個,sdff 全部則是 28 萬個,如果不檢查 sdff,在遞迴函數內全部只需要 5 秒鐘,比原本的 6 分多鐘少了很多。

之前做了一些調整後,最好時可以壓在 5 分鐘內。

OK,這個問題的本質是我有一些 Tcl Array,因為我在遞迴檢查時,如果符合某個 cell name 我要記錄他的 hierarchy 資訊,原本我的寫法是:

set tmp myarray($cell_name)
lappend tmp $my_hier_info
set myarray($cell_name) $tmp

原來我可以直接這樣寫就好了。

lappend myarray($cell_name) $my_hier_info

如果是這樣的話,全部就只要 5 秒鐘就好。

這樣改可以生效是因為我減少了很多不需要的賦值和設值動作。

2025年3月10日 星期一

bash script 的框架

今天為了解一個小 bug,花了我快 40 分鐘。

雖然早就知道 local 的用法,但今天沒有意會到之前寫的程式沒有在函數中的參數加上 local 修飾字,導致我不小心改到外面的全域變數,難怪看了快 40 分鐘才找到問題。

我覺得,即使是 bash script,最好還是要用 main 函數並在所有的函數中都使用 local 關鍵字修飾變數,這樣就不會誤改到全域變數了。

下面是示意圖,Line 13 就是忘了加 local 導致改到全域變數了,這也是我今天耍笨的地方。

2025年3月7日 星期五

Verilog $value$plusargs

平常用 iverilog 時,最常使用的是 -D 選項,此選項是 for 編譯時期使用。

如果我們想要在 simulation 時期傳遞參數,就必須使用 Verilog-2001 新增的語法 $value$plusargs

既然是 simulation 時期,故必須在模擬時傳遞參數,也就是需要傳遞參數給 vvp 這支程式。

module TB;
reg[512*8:1] _new_path;
initial begin
if ($value$plusargs("NEWPATH=%s", _new_path)) begin
$display("%0s", _new_path);
end
else begin
$display("No NEWPATH");
end
end
endmodule

vvp -n test.vcd +NEWPATH="XXXXX"

2025年2月26日 星期三

netlist_treeview

沒想到我的 netlist_treeview 還有隱藏版功能?

顧名思義,我這支 tcl 程式主要目的是用來瀏覽 netlist 用,但 module 或是 instance 的 regex 語法不管是 RTL code or netlist 其實都是一樣,故他其實也是可以開啟 RTL code 無誤XD

目前只有一個問題,我的 instance regex 語法本來就會避開單行註解,故這部分沒有問題,不過當 instance 是在多行註解中,之前 parser 為了快速處理,連我另一支用 Python 寫的 netlist parser 處理單行的機制都沒有,故我沒辦法避開這樣的情形。

查了一下 Standard 2005,還好他不允許巢狀註解,故要快速處理就很方便了。


順便查了一下 Standard C11,同樣也是不允許巢狀註解。


剛好想到為什麼之前買的 C11 這麼便宜?原來有這樣的疑問不只我一個,我們可以在這個討論串找到解答。

簡單來說,INCITS/ISO/IEC 9899-2012 是美國內部採用的標準,所以賣得比較便宜,當初不知標準險惡,以為台幣兩千是正常的(我以為這樣已經很貴了XD),直到最近買了兩份 IEEE Standard 噴了兩萬,我才知道以前的我還是太嫩了XD

2025/02/26 更新

看似簡單的東西,沒想到也會犯下低級錯誤,還好只花了幾分鐘就想到了XD

set is_multi_comment 0

if {[string first "*/" $line] != -1} {
    set is_multi_comment 0
} elseif {[string first "/*" $line] != -1} {
    set is_multi_comment 1
} elseif {$is_multi_comment == 1} {
    # do nothing
}

不小心把最後一個 elseif 放在第一行,故永遠不會脫離。

另外,下午也開始嘗試處理 clock tracing,果然跟我想的一樣麻煩。

不先規劃好遞迴中止條件,也沒先歸納出 clock path 的一些態樣,真的很難把程式寫好。

還好我不趕時間XD

2025年2月23日 星期日

升降桌的隱藏用途

最近常在 IKEA 買椅子,好坐的大概都被我買回家了XD

除了 Aeron 沒買過,逛了那麼多家的椅子專賣店,感覺似乎背後都是差不多的台灣工廠製造?我覺得除了專業客製外,其實很難找到完全合身的電腦椅。

以前也曾在大安公園附近的一家專賣店試過 Aeron,可能那張椅子是老闆自己的,不是要拿來試坐的,故也不覺得好坐。

其實 IKEA 的椅子不算難組,最麻煩的地方就是坐墊跟椅背結合的時候,這時如果家裡有張升降桌,所有問題都可以迎刃而解,不論椅背高度都可以調整升降桌來配合組裝!


除了椅子之外,又買了個零錢包,記錄一下尺寸,以後才知道要買多大的。

12 x 9 x 2

2025年2月21日 星期五

2025 week 08 新玩意

01. bash script pointer to variable

有時候,我們就是需要變數的變數,原來只要像下面這樣,就可以達到此目的。

不論是一般變數或是陣列都可以用。


02. bash script in EDA world

今天在試 Tessent run_synthesis command 時,發現它產生出來的 script 居然也是 bash script 而不是 csh script。

這是否意味著,只能用 C Shell 跑 EDA 工具的都市傳說早就已經不復存在?

坦白說,bash script 還是比較好用!

2025年2月18日 星期二

gtkwave configuration

因為沒有 license 的關係,故最近都是用 iverilog + gtkwave 跑 simulation。

可能之前就是用這樣的 solution 來學習 Verilog,故我本身還蠻習慣的,我甚至覺得 gtkwave 還比 nWave 好用?

不過預設的 GUI 設定不是很好用,每次開啟都要重新指定一次,這些設定也不會儲存在 .gtkw 的波形訊號設定檔中。

我們可以用 man gtkwaverc 來看有哪些參數可以指定,並將想要的參數儲存在 ~/.gtkwaverc 的檔案中。


不過,Windows 下似乎不起作用?

改天再來看看 source code 好了。

2025/02/19 更新

Windows 檔名需用 gtkwave.ini

如果要指定字型,waves 一定要比 signals 大。

fontname_signals Monospace 12
fontname_waves Monospace 10

2025年2月17日 星期一

The pointer in EDA flow

EDA 世界中,一些 command 拿到的變數,我們可以把他想成是一個指向 object 的 pointer。

因此,如果直接用 puts command 印出該變數,我們只會得到一個類似指標的位置。

DC 可以使用 get_object_name 得到字串。

Tessent 則是使用 get_name_list 得到字串。

2025年2月16日 星期日

Lenovo TrackPoint II 小紅點鍵盤

因為暗黑 2 聖騎士已經升到 99,需要在書桌玩遊戲的機會也不多了,拿掉外接的 HDMI 線後,我的螢幕就只剩三條線了:

01. 電源線
02. DP 線連到筆電
03. 外接 Lenovo TrackPoint I 小紅點鍵盤(2021/06 購入,NT 2680)

看來還是只能購買 2 代藍芽版了XD

Amazon.com 價錢是 USD 107.1,如果要加快運送速度,大概要再噴個台幣 1500 多。

想想並沒有那麼急,就走一般運送方式就好。

這台已經是 4 年前多的產品了,好像也沒有出下一代了?

台灣也沒進口,露天看到有人賣 4000,坦白說也不貴,但已經下單了就懶得改。

後來又看到有人出機械鍵盤版,之後聯想不出後,我可能也只能選這個了。

不過真的走到這一步,我應該還是不會買,機械鍵盤根本是邪魔歪道,傷敵一千也會自傷八百。

2025/02/26 更新

昨天下班已經收到包裹了,還好沒多花錢加速運送,原來出貨賣家在日本也是有好處的,大概 9 天就收到貨了。

拿到的第一個感想就是好重,比我現在的有線鍵盤重了不少,改天開始用新鍵盤後再來更新。

2025/02/27 更新

這支鍵盤不知道為什麼中間整塊稍微有點浮?不影響打字就算了,看了一下背面是 2024/10 製造。

整體來說很明顯的比有線鍵盤大了一圈。


FN + DEL 應該是藍芽配對。

下午試用的結果,因為滑鼠左右鍵比較淺,沒有前一支的突出感,感覺不太好分辨是否有按下滑鼠左右鍵。

整體來說,目前無線鍵盤試用的感覺就只有無線這個優點而已。

2025/03/03 更新

今天把有線鍵盤拿去辦公室了,原本快 20 年前買的 SK-8835 就只能功成身退了!其實還很好用,但目前在 Windows 10 下會有個問題,如果從休眠狀態回來原本禁用的 touch panel 又會被啟用,每次都要自己手動關閉。

2025年1月26日 星期日

暗黑 2 LV99 聖騎目標達成

2024/12/25 聖誕節晚上升上 LV98 後,幾日之後計算了一下 TZ 經驗,升上 99 似乎不是很難?

雖說不是很難,但每天也都要玩個幾局。

我除了中間有幾次放假時間用 tcl/tck 寫 netlisttreeview 外,幾乎每天都有開局,還要加上半夜睡不著覺的奮鬥時間,才順利在今天升上 LV 99。

中間還打到人生中第 3 顆貝。

還打到人生中第一雙戰旅,這也讓我的弓馬暫時成為完全體


升 LV99 瞬間

LV99 裝備

終於可以放下暗黑 2 了XD

放上我這隻槌丁的英勇照片,雖然只有 12K 的祝槌威力,但身拿執法者,每個 BOSS 都可以輕鬆 KO,遇到電鬼就換雷力 + 法拳,雖然犧牲了手套的 20 攻速 + 20 以上的電火炕,但可以不用一直喝紫水還是值得的,這樣我切執法者的時候就只剩 60 攻速,但我的狂熱加物品給的應該也有 28 吧,遇到衰老勉強也還過得去。

暗黑 2 是一個很有深度的遊戲,雖然說大部分的流派都被摸索得差不多了,但還是可以有自己的想法,畢竟自己玩得開心最重要XD


晚上買了兩份 SPEC 待看,還真不是普通的貴,居然要兩萬塊找零頭?

雖然過年很多事要做,可能也沒時間觀看,畢竟也還沒開始大掃除XD

不管如何,我的心意還是到了…

2025年1月19日 星期日

tcl 函數呼叫原則

上上星期找到一篇文章,內容是關於 tcl 常見誤區,可惜存在辦公室電腦,家裡 Chrome 並未同步。

其中有一段是在敘述如何決定何時傳給 tcl 函數的變數,前面是否要加 $?

大原則是這樣:

01. 如果要改動到原變數的值,則不要加 $。
02. 如果需要原變數內容的時候,則加上 $。

目前看來大概可以解決 8 成以上的困擾。

目前用過的函數,除了 info,array 相關,lreplace 是例外。 

2025年1月4日 星期六

從做中學

之前其實有看過 tcl 語法書,但因為並沒有真正的拿它來開發專案,所以語法也是看過就忘了。

最近真的拿它來開發我自己需要的工具,終於也算是可以拿它來做點事了。

如今的我,也可以說是對 tcl 略懂略懂了?

當然很現實的就是前一陣子為了查字典用的 bash script,現在也不太熟了!

我這個人的程式人生就是一直在不同的程式語言或是框架中渡過…

國中以及大學為了撥放 MIDI 使用的 QBASIC
不會寫程式時玩 Linux 的簡單 script
第一個學會的程式語言 C
BCB C++ 開發 GUI
BCB C++ / PHP / AutoIt 開發類 IT 人員使用的工具
目前公司第一個部門用過的 Android  Java / C++ / wxWidget  C++ / Node.js / Windows Batch / GNU Assembly / Go / Rust / C# / Python
為了電子書購買金額統計學會的 Chrome Extension

最後則是現在部門的 Verilog / Linux script / Makefile / tcl/tk

想我一生,還真是命途多舛XD  

學程式寫程式到現在也 20 年了!

學會什麼,換個專案馬上就忘記什麼,從沒待過賺錢的地方使用 domain know-how 來累積工作上的漂亮履歷!

難怪到現在 github 星星全部專案加起來也才 100 出頭XD