pretty code

2025年6月17日 星期二

老人安置

最近幫媽媽處理一些親屬老人安置補助的東東,記錄一下避免忘記。

假設符合一定條件,這個補助計畫網頁文字為「低收入戶、中低收入失能及保護安置老人接受長期照顧機構安置補助計畫」,假設是新北市政府 114 ~ 115 年度,養護類安置費,每個月 2 萬 4 千元,假設中途因病住院,30 日內都可以保留並仍予補助。



這個金額最早沒那麼多,陸續有調整,108 年度為 2 萬 2 千元。

另根據「低收入戶及中低收入戶傷病住院看護費用補助」說明,符合資格者,一天可請領看護費用 1,800,目前看護行情一天至少 2,800。


假設是喪葬費,最高 3 萬元整,亦可以參加聯合公祭,可用「113 年度新北市聯合奠祭實施計畫」關鍵字查詢,內有項目細節可看。

2025年6月14日 星期六

Kobo 網頁又改版了

我想這個標題未來應該會一直出現XD

不得不說,人家讀墨網站就沒有那麼多問題,就你 Kobo 喜歡將 HTML  改來改去,真是腦袋有洞?


罵歸罵,還是要看一下如何修改,雖然我現在已經很少看工作以外的書了?


這次顯示購買記錄一頁有幾個項目的地方又從一行改從跨行了?

幸好,Javascript 的 regex 似乎可以支援跨行,即使我沒有加上 m 選項?

總之,現在可以就好了,我也懶得查了?

畢竟,現在國事如麻,百廢待興呀XD

期待的功能終於有人實做了

之前一直覺得是不是哪邊文件沒看清楚?不然沒道理 Yosys 合成出來的都是 escaped identifier 的名稱,這樣看起來確實是不好看!

剛剛本想直接 trace code,想說還是先用關鍵字在 issues 查一下,果然目前是沒有 rename 這樣的機制。

幸好,有一位強者提交了這個功能,等到通過後,我就可以拿 Yosys 綜合 ORFS 裡的一些專案得到一個相對大型的 netlist 來用,不然想要開發或測試一些功能都不方便。

目前還是只能看到醜醜的 escaped identifier!

看到這樣的結構,想開發一些功能都沒勁了XD

2025年6月12日 星期四

第二次確診記錄

約莫是五個星期前感冒過一次,那次原本以為是確診,但跑了好幾家才買到的快篩測試後卻不是?不過我篩的時候已經是 8 ~ 9 天後的事了。

那次咳嗽大概是一個星期多才變比較少,一天下來也是會偶爾咳個幾下,印象中以前感冒不會拖那麼久,但不排除是以前有看醫生的緣故?哭哭,我從小看到大的醫生已經退休,公司附近的診所評價都很差,不太可能為了這個上台北看病。

上星期五下班開始,體感好像咳嗽又變嚴重,好像六還是日開始有流鼻水,星期一咳嗽達到巔峰狀態,好險只持續一天,當然睡覺的咳嗽還是一直持續,晚上不好睡覺。

星期二下班時看老婆都沒吃飯,一問之下才知道她已經肌肉痠痛一整天,也已經去我看到評價不好的診所看過病,不過醫生不覺得是流感故也沒幫她做快篩。

一整天也不說,下班時打電話也不說,害我只好三兩下把飯扒完,開車去一個我查到評價還可以的診所。

由於又繞了一圈去停車,等到我走路回去時看診人數已經爆滿,還好我老婆已看完在等快篩結果中,不過為了讓老婆早點回去休息,故我自己也沒機會看病。

篩的結果不是流感,不過醫生覺得應該是新冠,想知道的話自行購買快篩確認,因為不影響他開藥的決定XD

還好這次購買很順利,不用像上次一樣要跑多家才買到。

回到家老婆累到洗完澡就睡了,反正快篩有多買,順便來測一下好了?

滴完後,只不過把東西轉頭丟到垃圾桶的光景,無意間一瞄之下,居然是兩條線?這也太快了吧,上一次確診快篩時也沒那麼快出現兩條線?


不過單從顏色來看,似乎沒有很深?

由於隔天老婆要去南部出差,她中午又跟同事吃飯草草結束我電話,故我也不知她近況如何?

昨天還沒下班就聽到位子傳來老婆的訊息震動聲,等跟同事討論完回到位子一看,原來她也中獎了,不過她更誇張,據她本人說法,一滴下去,流過去馬上兩條線。


還好電話中聽起來精神還可以,除了下午一直拉肚子以及輕微想吐!

虧我上星期五下班後在家也一直戴口罩,沒想到她還是中了,雖然我一直覺得是她傳染給我的XD

在家也戴口罩,出門及上班也一直戴,即使是一盒 300 的口罩,我的耳朵也已快承受不住。

Verilog - Implicit declarations

在 Verilog 2005 4.5 中提到了 Implicit declarations。

簡單來說,變數可以直接使用XD

在我這種寫純C 出生的看來,這種 coding 真的是大逆不道!

如果只是一個地方忘記宣告就算了,偏偏我看到的卻是幾乎所有的變數都這樣使用,重點是這個 Testbench 還是御三家中的某個 IP 的 Testbench。

一個要錢的東西你這樣寫,我只想問候他老母?

不過也不排除這樣寫是故意的,大大增加你修改 Testbench 的不便XD

雖然我現在就是要確定你每個 net 給什麼值,假設你在這個 Testbench 中 include 一堆檔案,我得一個一個看過去才知道你到底是否有在哪個地方宣告並賦值?這大大增加了我 trace code 的不便!

尤其這裡用了一堆 define,其對應的 endif 也沒給註解!

我實在是很難一眼看出我要的東西到底在不在。

第一個問題很簡單,如果是自己寫的 Verilog,加上下面語法即可報錯。

`default_nettype none


第二個問題就有點小麻煩

理論上如果我知道所有的 define 是什麼,我是可以透過 iverilog 的前置處理來幫我去掉不要的 define,再用 sed 去掉拿掉 define 留下來的連續空白,我就可以有一個清爽的 Testbench 來用。


但問題是我連完整的 Testbench 都有缺,我根本無法確認所有的 define?

2025年6月4日 星期三

每天都對 Vim 有新的體悟

Vim 用到現在,只差覺得摺疊沒那麼好用?

今天忘記要查甚麼資料,試了一下 set foldmethod=indent,想要看一個整體的感覺比較方便,一試之下,好像還可以?

尤其我的 code 一向很注重整齊,現在設成 default 後,打開自己的 code 感覺清爽多了!


只恨自己沒有早一點用 Vim,不然生活應該會更開心XD

2025/06/05 更新

zA 打開所有折疊
zM 關掉所有折疊

如果折疊不如預期,可以下 set sw=2 來幫助折疊更多。

原來我對 Verilog 理解有誤

一直以為在 Verilog 中,想要用某個 module,一定要建立一個實體,沒想到好像不是這樣?

這幾天又把手上的 IP test 相關 flow 又看更深了一層,在看的過程中就覺得哪邊怪怪的,原來是 module 不用一定要建立實體?

晚上回到家,寫了一個測試來驗證,好像真的不用,難道是 System Verilog 的緣故?先記錄一下,回頭再來確認!


2025/06/05 更新

早上翻遍了 Verilog 規格書,還是看不到不用實體化的理由?

於是問了一下 Bard,他也是一直跟我說不行,直到我說我用 iverilog + vvp 是可以跑的,他才告訴我一個答案,一開始我還半信半疑,不過,有了方向就好解決,打開 -v 選項一切都無所遁形!

下面是 Bard 的回答

你觀察到的現象是正確的!

你的 tb.v 程式碼能夠被 iverilog tb.v + vvp a.out 正確執行,這主要是因為 Icarus Verilog (iverilog) 編譯器的一個特性,以及 Verilog/SystemVerilog 語言中階層式參考 (Hierarchical Reference) 的規則。

Icarus Verilog 的行為:

自動辨識頂層模組 (Top-Level Modules):

iverilog 預設會將那些沒有被其他模組實例化的模組視為頂層模組 (top-level modules)。

在你的 tb.v 檔案中,cfg 和 test 這兩個模組都沒有被其他模組實例化,所以 iverilog 會將它們都視為頂層模組。

這意味著 iverilog 會為 cfg 和 test 各自創建一個獨立的實例,位於模擬器內部的一個抽象的 "root" 級別。

即使 cfg 模組沒有被 test 模組直接實例化,但 test 模組可以透過階層式參考的方式來存取 cfg 模組內部定義的訊號。

在 iverilog 預設將 cfg 視為頂層模組的情況下,它會被分配一個預設的階層名稱,通常就是它本身的模組名稱,或是在內部樹狀結構中被編譯器視為一個根實例。

所以,當 test 模組嘗試使用 cfg.num 時,iverilog 能夠解析這個路徑,找到 cfg 這個頂層模組的實例,並進一步找到它內部的 num 訊號。

為什麼這在真實硬體設計中不常見:

雖然 iverilog 允許這樣做並能正確模擬,但在實際的 RTL (Register Transfer Level) 硬體設計中,這並不是一個好的設計習慣,通常會避免。

缺乏明確的連接性: 

在硬體中,你必須明確指定一個模組如何與另一個模組互動(透過實例化和端口連接)。你目前的寫法模糊了這種關係,讓人難以理解訊號是如何傳遞的。

模擬器/合成器行為差異: 

雖然 iverilog 支援這種階層式參考,但其他模擬器或硬體合成器 (Synthesizer) 可能對這種寫法有不同的解釋或根本不支援。合成器在將 Verilog 程式碼轉換為實際電路時,需要明確的連接關係,而這種直接的階層式參考對於合成器來說通常是難以理解和實現的。

可讀性與維護性: 

這種寫法降低了程式碼的可讀性。當專案變大時,很難追蹤哪個模組直接存取了另一個模組的內部訊號,這會增加維護的複雜性。

模組的封裝性: 

模組應該有良好的封裝性 (encapsulation),即外部模組只能透過其定義的端口與之互動,而不應該直接進入其內部存取訊號。直接的階層式參考打破了這種封裝。

總結:

iverilog 允許你的 tb.v 程式碼正確執行,是因為它有足夠的智慧來辨識多個未被實例化的模組為頂層模組,並支援跨層次的階層式參考。

然而,在撰寫可合成的硬體描述語言時,強烈建議遵循實例化 (instantiation) 和端口連接 (port mapping) 的標準方式來建立模組之間的關係,或者使用 參數 (parameters) 或 SystemVerilog 的封裝 (packages) 來定義全域常數,以確保程式碼的清晰度、可攜性以及可合成性。

下面是我回家測試的結果


確實使用 -s 指定 top module 後,iverilog 便會報錯,可見 Bard 沒有騙人XD

2025年6月3日 星期二

Vim profile test


從前幾天買的書中學到一招,可以觀察 Vim script 的函數執行時間。

目前不確定 SELF TIME 有沒有包含 count 的?

2025/06/03 晚上更新

回家又做了一次,順便記錄一下相關指令。

:profile start xxx.log
:profile func *
:profile file *


這次抓的是詳細的資料圖,可以看出最花時間的是往回找 module 的那個 execute 指令。

問題就是出在 search 而非是那個 redraw 清理下面狀態列的指令。

2025年5月30日 星期五

又上天龍


Vim script 細節雖然大概都知道了,手上也有謎版 PDF 以及英文電子書了,難得再次來到天龍國的天瓏書局,不買真的說不過去,於是我又多砍了幾棵樹了XD

通識課這本我其實只想看其中的兩頁,不過嗎,書本不嫌少,知識不嫌多,還是需要一些東東來傍身?

絕世武功動輒都要練個好幾十年,但是現代人欠缺的就是時間呀XD

2025/06/01 更新

原來上面中間那一本已經有第 2 版的英文電子書了,剛試閱了一下,出版社還很貼心的附上連結,只要傳給他購買證明,出版社便會寄給你免費的 PDF 電子書,那還等什麼XD

於是我的 Vim 藏書加上這本,已經來到 6 本之多!剛好 3 本電子書 + 3 本紙本書XD


2025/06/04 更新

原來外國人也會嘴砲,到現在都還沒收到 PDF 電子書,感覺不好XD

2025年5月29日 星期四

Download UNC files to WSL2 folder

今天遇到一件怪事,差點以為是客戶給的東西裡面的東西,搞了半天居然是因為標題所描述。

當我們把 UNC files 複製到 Windows WSL2 folder ( \\wsl2.localhost ) 時,不知為什麼會產生 xxx:Zone.Identifier 的檔案。 

還好我突然福至心靈的去檢查原始資料,不然就糗大了XD


2025/05/31 更新

即使從 \\wsl2.localhost 裡面複製到 \\wsl2.localhost 其他位置,一樣會產生這個檔案。

2025年5月28日 星期三

global + ctags + Verilog

global 預設只能讀懂 5 種程式語言,如果需要 parse Verilog,我們需要 ctags。

在 Linux 可以安裝 universal-ctags,Windows 上也有對應版本可裝,不過 Windows 需要額外準備 gtags.conf。

執行 gtags 時只要加上 --gateslabel new-ctags 即可,這樣針對 Verilog 檔案便會呼叫 ctags 來 parsing。

目前看起來不管是 gtagshtags -snaglobal 都可以正常執行。

當輸入是 netlist 時,由於 design 集中在一個檔案中,這會導致 htags 產生的單一檔案 html 過大,我公司電腦自己已經加到 16G 記憶體,但還是因為使用記憶體過多導致 chrome 會讀不完整個檔案一直在轉圈圈,不過使用 global 查詢都正常。

改用 ORFS 的 ibex 來當例子測試看看。


目前有一個想法,想要在 global 的基礎上動些手腳,將選示行號的地方改成 module name,這樣對 trace signal 比較有幫助。

所以流程大概是這樣。

01. 呼叫我的程式,傳入 netlist。
02. 執行 gtags 得到 3 個資料庫檔案。
03. 將 netlist 的每一行建立 map 對應,據實測即使 netlist 有 3000 萬行,大概也是 10 ~ 20 秒就可以建立完畢,也就是用空間換取時間的做法。
04. 程式進入 while loop,監聽剪貼簿或是 socket。
05. 收到 Vim 傳來的 signal 便呼叫 global 查詢。
06. 將圖片的查詢結果中的行號改成 module 並顯示改過的結果。

另外,今天有查詢了一下資料,目前看來 DVT Eclipse IDE 也許是一個可以試試的工具,不過需要掏出魔法小卡而且似乎是訂閱制?

2025年5月27日 星期二

Vim vtags

雖然經過這一年的洗禮,我已經習慣了 Vim,也把自己購買放在公司專用的 UltraEdit 移除了。

即便上星期寫了一個 trace variable 並顯示位於哪個 module 的 Vim function,想要好好在 netlist 中 trace variable 還是很痛苦,沒有 EDA 可用就是這麼辛苦XD

今天看到一個 vtags 的小玩意,想說是不是能幫助我看一些東西?沒想到這個東西不能在 Windows 上執行,還好我有 WSL2 環境,果然在 Linux 就可以順利執行。

可惜,手上的 netlist 過於龐大,vtags 會讓 Vim 當機,故我也沒看到他的廬山真面目!

回家試了一下,左邊是 <Space> + v,右下是在 module 那行執行 mt 的結果,看起來似乎跟我的 netlist_treeview 差不多意思,看的都是 hierarchy 的結果,並非我想的訊號追蹤?


還有像 ORFS 裡面的 jpeg_encoder 因為 yosys 綜合後,會用到很多 escaped identifier,故 vtags 也無法支援。


難道,我又要自己寫 tool 了嗎?這可是一件大工程呀!

另一個可以嘗試的方向是 GNU global,看起來只要找到 plugin,就可以處理 verilog 的專案?

2025/05/27 再次更新

原來是我耍笨,看起來可以用來追蹤訊號,詳此處

拿它來改出我要的工具?

2025年5月25日 星期日

Tne Entity

終於在昨天看了 MI8,雖然我從 MI5 才開始進電影院看,但鼎鼎大名的 MI 以及阿湯哥誰人不曉?看到阿湯哥的名字就知道是可以進電影院看電影的指標XD

我最喜歡的幾個片段中,一個是女總統嘴上說把阿湯哥關起來,但事實上卻是放任阿湯哥去拯救世界,看到門外的直升機,不誇張的說我都哭了,那種被人信任的感覺,也不枉阿湯哥多年來出生入死卻還不能擁有跟一般人一樣正常的生活。

另一段就是女總統幕僚詢問是否要跟兒子通電話,那時我才明白她決定犧牲兒子所在的城市,先不管別國人民,她如果不這樣做是要如何跟美國人民交代?這才是我心目中理想領導人的樣子。

原本被網路上的文章標題誤導,害我以為阿湯哥這集要領便當!當卡特拔出隨身碟後,我都想到下一幕可能是因為阿湯哥降落傘被燒了導致摔死,眾人去無名碑前緬懷阿湯哥的鏡頭,看到白傘的一幕,我差點都傻眼了,網路上還真會亂扯,果然是農場標題殺人,這也是我覺得目前網路最糟糕的一件事,充斥一堆垃圾資料!

前幾天才買了美國隊長4,也算是我對自己的一個交代,既然集齊了美國隊長 1 ~ 4,是不是應該趁此機會也把 MI 1 ~ 8 集齊呢?

2025/05/27 更新

就在星期日傍晚一口氣買齊了 1 ~ 6,之前就買了 7,現在就等 8 出來了XD

2025年5月22日 星期四

今年我看過的騷操作

今天在試跑一個 IP 的 testbench,第一次看到這樣的騷操作XD

首先,在預設 c shell 的環境下,呼叫一個 c shell 語法的 script 來設定相關變數,接著再跑一個有指定 shell 的 bash script 來跑 testbench。

由於我不是在工作站,故我不能在預設的 bash shell 下另外用 tcsh xxxx script 的方式來設定變數,除非我把呼叫 bash script 的 command 寫在 c shell script。

我個人是這樣覺得啦,既然 EDA 跑在 bash shell 不會有問題,事實上御三家的一些 gen 出來的 tool 也是用 bash 語法寫的,這樣大家都統一使用 bash script 不就好了,何必把問題搞到那樣複雜?

即便是號稱一天上班就用了 5 種程式語言來工作的我,還是很討厭一直在 context switch,人生呀,輕輕鬆鬆簡單過不好嗎XD

2025年5月18日 星期日

又到了一年一度清潔冷氣的日子

前一陣子感冒,拖到今天才有空清潔冷氣,下星期老婆應該就可以爽爽吹了XD

去年因為被排線兩邊卡榫誤導,一直無法順利退出排線,只能一手扶住外框,一手伸進出風口擦拭,今年不理兩邊卡榫,硬用暴力演算法解題,終於順利退出排線?

整個外框拆除後,整體清潔容易多了,一台去年才換的冷氣,看起來跟新的一樣,鼓風輪稍微用紙巾接觸的結果也沒有明顯髒污,而另外一台 2021 年疫情時換的冷氣,保麗龍就有明顯的發霉,因為去年有擦過,故知道是去年怎麼擦都擦不掉的汙垢,目前也只能就我能清潔的清潔,不管怎樣,一定是比只能從外面擦拭乾淨。

去年換掉的那台窗型變頻舊冷氣,只過了 7 年就因為底盤卡住髒汙而滴水,考慮了一下整台換新比較快搞定,不然去年夏天就沒有冷氣可吹了,這樣看來,窗型變頻冷氣大概也是要 5 年就找人清潔較好,不然就會因為底盤卡住髒污而滴水。

日立變頻只有雙吹才是日本製壓縮機,台製明顯的聲音大聲多了,變頻的好處就是稍微安靜,但即使是日立也不用覺得會多安靜,不過我也只有窗型能夠選擇,不論是書房還是臥室,大概就是選擇 3 萬多的機型即可,再上去就會因為太大而裝不下,其實我可以選擇型號 28 的,選大一號的好處就是哪邊冷氣出了狀況,還可以用另一台將氣流導到另一個房間,至少撐過炎熱的夏天是沒問題的,根據去年實測的結果XD

房間:RA-36 NR(3.69 KW)
書房:RA-36 HV1(3.69 KW)

順便拍個圖記錄一下,外框拆除要看此篇記錄

2025年5月17日 星期六

不枉費我放假幾個小時的努力

在一個 netlist 中,想要追蹤一個信號是件很痛苦的事XD

如果是可以開啟 EDA 的環境,比如說透過 Tessent Visualizer,只要準備好相關 library,滑鼠點擊幾下,就可以看到來龍去脈。

但很多時候,我可能只有 Vim 可用。

之前為了這種情況,寫了一個 map 自動將某個 module code 複製起來,使用 tab 開啟複製到新分頁,這樣查詢時就不會過頭,避免已經跳到別的 module 而不自知。

早上出門前突然想到,是否可以在按下 n 跳下一個位置時,顯示目前位置所在的 module name 以及行號呢?

下午回家洗完澡後,扣掉晚上吃飯時間,大概也寫了 3 ~ 4 個小時有吧?

終於在剛剛完成了,雖然只有不到 100 行 code,但卻遭遇到很多問題。

比如在 statusline 顯示變數,怎樣用 regex subgroup 切出我要的 module name,還有如果 map key 還是用 n 會一直進入無限遞迴的問題,以及針對 statusline 的修改即使是對的,但還是會報錯,必須重新出去 Vim 再進入一次才會正常的問題等等。

真的是得來不易呀,也不知道是否真能有點幫助?

但不得不說,完成的那一瞬間,爽度真是一百分有XD

2025年5月16日 星期五

好像會又好像都不會

Vim script 寫到現在,有時候會覺得好像自己什麼都不會XD

早上因為一直咳嗽,很早就起來了,想要為自己的 Netrw 加一個功能,加到剛剛都還不成功。

快要上班了,只好先用 patch 搞定,留下 echom debug 訊息,之後有空再來尋求正規解法XD

2025/05/17 更新

目前先用個變數記住 current buffer number,每次進到我的 Netrw,只要現在 buffer number 跟之前不一樣就可以放心的砍下去,好像還可以。

至於遇到 C:\..\ 這樣的路徑,也就是一直按 - 鍵,已經切到根目錄的情況,多一道檢查手續的 patch,好像也還行,暫時先這樣解決吧。

現在只差到底是否要針對 Windows 與 Linux 區分目錄符號?感覺說明看起來是不用?

目前我的 .vimrc 可以用在 

Windows gVim
Windos Git Bash
工作站 Vim

嚴格來說,也可以用在不管是公司還是家裡電腦的 WSL2 Unbuntu,但是因為工作站 Vim 版本比較舊,我的 Netrw 一些函數無法呼叫,只好還是用 Vim 內建的 Netrw。

我也懶得再去區分了XD

2025年5月14日 星期三

dcman

之前在某篇文章學到 dcman 的用法,讓我可以在沒有 DC license 的情況下還是可以查詢指令說明。

不過,對於 message ID 形式的訊息,比如 VER-970 這樣的 ID,只能在 dc_shell 下用 man 查詢。

雖然辦公室的人很少用 DC,但只是想查個東西,還要等待 DC 啟動,少說也要好幾秒,更別提為了不讓到處都是 DC 的 command.log,個人習慣還是先切換到我自己的 temp 目錄才去啟動 dc_shell。

雖然我有設定 alias 不用打那一長串指令,但還是覺得不開心XD

昨天研究了一下,終於知道為什麼原來的 dcman 不起作用!

man -M 指定的資料夾中,man database 需要符合一定的結構,就我初步看來 DC message ID 形式的 man database 多了一層資料夾,難怪都會查無資料。

解決方式也很簡單,另外寫一個簡單的 bash script,遇到像是 VER-970 這樣的查詢,使用 - 割出前後字串,前面字串就是那多了一層的資料夾名稱,接著再接上 VER-970 以及後面的副檔名即可。

str=$(echo $1 | sed -En 's/([a-zA-Z]+)-(.*)/\1 \2/p')
str=($str)

folder=${str[0]}

整個查詢會變成下面這個樣子

man -l xxxxxxx/VER/VER-970.n 

測試了一下,果然如我想像中一樣可以順利執行,也順便測了 C2 C3 C9 等 DFT 錯誤訊息,目前看來都還可以正常工作。

另外,跟這個主題無關,為了讓自己的 bash script 更有彈性,有些跟著 script 的設定檔,最好還是指定 script 所在的 folder 變成絕對路徑,這樣的好處是當你使用 alias 執行自己的 bash script,我們可以切到要傳遞檔案的那個路徑,這時就不會有找不到設定檔的錯誤發生。

還有要傳遞的檔案,最好也是使用絕對路徑,這樣傳進去 EDA Tool 裡面也不會找不到檔案。

其實不管是 Python 或是 Go 也是如此,畢竟我們會希望把工具放到某個路徑,而不是把檔案複製到工具路徑再去執行,這樣一來,執行路徑就會很清爽,工作起來也更開心XD

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

file1=$(realpath $1)

2025/05/15 更新

據我所知,DC 有幾份文件是關於指令、變數以及錯誤訊息,如果習慣查詢 PDF 的話,也可以不用像我一樣使用 man 來查詢。

不過,兩邊的內容都是一樣的,坦白說,都一樣爛XD

個人覺得御三家中,文件寫得最好的是 Cadence,至少 LEC 是我覺得讀起來最順的,其次是 Simens,至於 Synopsys 我就不予置評了!

2025年5月12日 星期一

Vim tabline

看懂別人的 Vim plugin 有個好處,便是可以隨時把別人的 code 加到自己的 .vimrc 中!

當然,正規作法還是 follow Vim 的哲學,讓 plugin 可以 lazy loading,這樣才不會影響 Vim 啟動速度。

不過,我需要的都是小功能,加到自己的 .vimrc 還是比較方便XD

加了 tabline 後,好像已經快要沒有可以加的了?

tabline 原來只是個字串,但我們需要同時對所有 tab page 設定,格式就像下面那張圖的 command line 字串,其中 #TabLineSel# 表示目前 active 的 tab page。


之前一直不知道為啥 Windows Git Bash 會有問題,就在剛剛終於頓悟了,原來 Git Bash 中也放了一個 Vim,故我同時執行了原本的 Netrw 和我自己的,難怪每次切回 File Viewer 總是會報什麼 modifiable = off 的錯誤。


2025/05/15 更新

原來我還少設了一個 #TabLineFill#,難怪這個語法顏色怎樣都設不成功XD


2025/05/17 更新

雖然 Vim tab 不是這樣用的,但我還是習慣一個 tab 一個檔案。

不管是以前還是現在,我很少用分割視窗,可能我不喜歡使用太大螢幕的關係吧?

總之,適合自己的工作模式才是最好的,不用管別人怎樣界定。

這也正凸顯出 Vim 的過人之處,哪邊不好用就可以動手修改,難怪我會對他愛不釋手XD

2025年5月10日 星期六

Vim script 最佳學習指南


上面這個應該是我覺得寫得最好的,再加上又是中文,雖然是簡體,但還是比讀英文快多了XD

Learn Vimscript the Hard Way 雖然也是不錯,但我還是覺得敘事過慢,不用工作當然無所謂,但是畢竟人還要上班,一個傳統目錄的網站列表還是比較符合我的需求。

總之,一樣主題的書就是要多買幾本,彼此互相參照學習最快,想當年我初學 C 語言,C 語言的書買了至少有 10 來本,每本書都可以從中找到我所需要的部分,雖然這些書也早就丟光了XD

買過丟掉的書就不算了,手邊大概還有 10 來紙本書放在公司,如果電子書也不算的話,底下就是我手上目前僅存資訊相關的書籍了,很多都是我很喜歡的書,以後如果有出電子書我應該會再買一次來收藏,畢竟我家這般潮濕的天氣,什麼時候書會 gone 我都不知!

誠品就只有一個小小的櫃有資訊相關的書,至少有一半是 AI 和我不需要的文書處理的書,故每次跟我老婆說要去誠品巡巡田水,也不期待會有我想買的書。

買書還是得去天瓏,但想到要上台北還是覺得累。

不過今天還是買了一本我想看的書《無瑕的程式碼 - 函數式設計篇》,希望可以多少給我一些啟發。

人生好難呀XD













2025年5月8日 星期四

使用全域變數真的要小心,尤其在 Golang

可能我不常寫多執行緒的程式再加上常用很深的遞迴,故有時候我都會直接用全域變數XD

在別的程式語言也許還好,但在 Golang 的時候,一個變數是否是新的變數端看他是否有用到 :=

如果這時不小心,在操作全域變數時加上 :=,這時存取的就是一個新的 local 變數。

雖然除錯也花不了多少時間,但也是很難第一時間就馬上想到。

另外,為了收集資料,我的函數有時可以 for single job,有時也可以 for  accumulated job,如果這時忘記清空原本的全域變數,就會導致資料變成好幾次的累積結果。

以後除了很深的遞迴,我看還是少用全域變數XD

有時候也不是想用全域變數,但一開始如果不用一個 struct 包住變數,再加上隨著需求逐漸明朗,很多時候函數的參數都會逐漸膨脹,很容易就超過 5 個以上,再加上我的 code 大部分都函數化,有時一改就是好幾層,只好偷懶用全域變數XD

我想以我的 coding style 來說,一定要養成 struct 進,struct 出的習慣,這樣應該能避免全域變數的使用?

不過這樣 struct 也會變得腫脹,真是兩難?

2025年5月4日 星期日

我的第一版 netrw

終於有個樣子了,現在只剩下幾個問題
01. 沒有比較好的方法去禁止編輯,map key 不只影響 netrw 的 filetype,可能我的理解還是有誤。
02. statusline 不知為何沒有生效。

" for my file explorer
augroup explorer_group
    autocmd!
    autocmd BufEnter * call s:MK_Browse("")
    "autocmd FileType netrw nnoremap :q :q!
    autocmd FileType netrw nnoremap <CR> :call <SID>MK_Enter_Browse(<SID>GetCurrNetrwFile())<CR>
    "autocmd FileType netrw nnoremap i <ESC>
    "autocmd FileType netrw nnoremap I <ESC>
    "autocmd FileType netrw nnoremap a <ESC>
    "autocmd FileType netrw nnoremap A <ESC>
    "autocmd FileType netrw nnoremap x <ESC>
    "autocmd FileType netrw nnoremap s <ESC>
    "autocmd FileType netrw nnoremap y <ESC>
    "autocmd FileType netrw nnoremap p <ESC>
augroup END

function! <SID>MK_Enter_Browse(name)
    if isdirectory(a:name)
        let l:dir = a:name
        if has('win32')
            let l:dir = substitute(dir, "/", "\\", "")        
        endif
        
        execute ":e! " . l:dir
    else
        let g:MK_curr = getcwd()
        let g:MK_sv = winsaveview()
        execute ":tabe " . a:name
    endif
endfunction

function! s:MK_Browse(dir)
    " get current directory
    let curr = expand("%:p")
    if a:dir != ""
        let curr = a:dir
    endif

    " not directory, do nothing
    if !isdirectory(curr)
        execute ":set nocursorline"
        return
    endif

    " change folder for later using
    if getcwd() != curr
        call chdir(curr)
    endif

    " set up some options
    execute ":set filetype=netrw"
    execute ":setlocal nonumber"
    execute ":setlocal nowrap"
    execute ":setlocal cursorline"
    execute ":setlocal buftype=nowrite"
    
    " delete original path structure
    normal! dG

    let f_list = readdir(curr, 1)
    let n = 1

    " save paths
    let files = []
    let folders = []

    call add(folders, "../")
    call add(folders, "./")
    
    for f in f_list
        if f == ".swp" || f == "_.swp"
            continue
        endif

        let s = f
        if isdirectory(f)
            let s = s . "/"
            call add(folders, s)
        else
            call add(files, s)
        endif
    endfor
    
    " add folders
    for f in folders
        call setline(n, f)
        let n = n + 1
    endfor
    
    " add files
    for f in files
        call setline(n, f)
        let n = n + 1
    endfor

    " restore previous position
    if exists("g:MK_sv")
        if g:MK_curr == getcwd()
            call winrestview(g:MK_sv)
            unlet g:MK_sv
        endif
    endif

    " statusline
    call s:SetStatusLine()
endfunction

2025年4月28日 星期一

Add mouse menu on Windows

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\COMMAND_NAME\command]
@="C:\\ABC\\abc.exe %1"

[HKEY_CLASSES_ROOT\directory\background\shell\COMMAND_NAME\command]
@="EXE_PATH ."

2025年4月27日 星期日

My simple netrw plugin

自己寫 Netrw 果然還是有點勉強XD


上面是一個簡單針對 BufEnter Event 的函數。

為了讓他像是一個檔案總管,其實還有很多事要做。

比如說:

set nu!
set nowrap
針對檔案總管顯示顏色
原本使用者設定的 vimrc 裡面的東西要回復

族繁不及備載

至少開始有點感覺了…

2025年4月26日 星期六

快速 parsing 檔案

以前需要臨時對檔案 parsing,一般來說我都會選擇 C 語言,因為這是唯一一個我不需要 google 就可以寫完的程式。

年紀大了還要編譯有點懶,再加上需要做這件事的時候,往往還需要搭配 regex。思來想去,想用一個簡單一點,語法好記的語言,於是便決定以後就用 Tcl 了。

bash script 好是好,但是速度有點慢,不知道是不是我剛沒寫好的關係?

set input "c:\\Vim\\vim91\\autoload\\netrw.vim"

set infile [open $input r]
fconfigure $infile -encoding utf-8

set func_pattern {^fun(\s|!)+ (.*)\s*\(.*}
set end_func_pattern {^endfun}

while {[gets $infile line] >= 0} {
    if {[regexp $func_pattern $line >= null f_name]} {

    } elseif {[regexp $end_func_pattern $line]} {
    
    } elseif {[string first "winrestview" $line] != -1} {
    
    }
}

剛剛希望找到 Netrw 所有呼叫 winrestview 回復 cursor position 的地方,很可惜,確認了幾個地方,但都不是對的地方,我到現在還找不到開啟右邊視窗後,回到原本 Netrw 瀏覽視窗的地方,到底是哪個函數破壞了我自己回存 position 的意圖?


我甚至把所有的 winrestview 都註解了,還是解不掉這個行為,我開始懷疑我的方向錯了?

2025/04/26 晚上更新


想要把之前註解掉的語句回復,使用上面 Tcl 語法,遇到 UTF-8 編碼,還是有少數幾句會有問題,這個問題先記錄起來,以後有空再回來確認。

後來想到可以使用巨集來回復,只要先設定 set nowrapscan,不要讓搜尋從頭開始,這樣就可以設定下面巨集了。ˊ

01. / winrestview 先 trigger search
02. gg 回到第一列
03. qq 開始記錄
04. n^x<ESC>j
05. q 停止紀錄
06. 100@q 執行 100 次巨集,數字要比所有的 winrestview 次數還要多。

04 巨集最重要的是最後面的 j 也就是跳到下一列,這樣按下 n 才會往下一個 winrestview 前進。

2025/04/27 更新

既然 Vim 巨集這麼好用,今天一口氣在每個函數入口加上 echom function_name 的功能,但居然都不是呼叫 winrestview 的函數被觸發而是 s:NetrwInsureWinVars。

現在只能猜測是 Netrw 有去動 buffer 或是什麼我不知道的東西?

有時在想,自己寫一個 directory explorer plugin 會不會比較簡單?

Tcl global error

之前用 Go 重寫 tool 時,改由自己得到 Top module name,不再從 command line arg 取得。

覺得這樣也蠻方便的,故將 Tcl code 也比照辦理。

由於之前的 Tcl code 遞迴用很深,故我很多參數都是拉出來變成全域變數,就只是忘了在 proc 中加上 global var 宣告,害我昨天找了老半天XD

2025年4月22日 星期二

又回來 Golang 的世界了

花了兩天時間,將之前使用 Tcl + bash script + grep + sed 寫的工具,改用 Golang 重寫。

這一年來已經習慣了 script 的 free Coding 過程,突然回到編譯型語言,還真是有些彆扭XD

距離上一個使用 Golang 開發的專案,也有三年了吧?

不過,編譯型語言還是有好處的,比如一個原本要 54 秒的 netlist 相關報表,現在只要 15 秒即可搞定(之前慢是慢在 bash script,不是 Tcl)。

Golang 還有一個額外的好處就是很容易跨平台編譯,比如我在 Windows 就可以編譯出 Linux 上跑的 ELF 執行檔。

今天在電腦的 WSL2 環境,想要驗證一下功能是否正常,突然發現,原本上面那個例子,居然要跑到 200 秒?

我連 pprof 都用上了,但還是只能看到問題是出在 System Call 上,中間一度還懷疑到我有一個很大的 struct 變數,在遞迴函數裡並不是傳遞 pointer 的緣故!

也懷疑是否是用了大量的 fmt.Sprintf 導致!

最後看到一篇文章,才發現是檔案系統的問題,但我不太確定是 NTFS 的鍋還是 WSL2 + NTFS 的鍋就是了?

總之,要在 Linux 跑程式,還是要使用 Linux 相關的檔案系統比較不會有問題,尤其我的工具就是要寫一大堆跟 cell 有關的報表。

2025年4月17日 星期四

Declare function in Vim script

簡單來說,除了 map 指令呼叫的函數以外,我們都可以用 s: 來宣告函數是屬於 script 的,map 會用到的就是要用 <SID>


至於我們要如何來 debug 我們寫的 Vim script 呢?

下斷點等太進階,C 語言的 print 大法簡單好用。

使用 echom 印出訊息,使用 :messages 看訊息,簡單搞定。

又或是先將 code 寫在獨立的檔案,使用 :source 直接執行,確定沒問題後再移植到 .vimrc

官方建議將函數寫在 .vim/autoload 裡面而不是寫在 .vimrc,這樣的好處是不影響啟動速度,缺點是第一次用相關函數時需等待載入。

2025年4月16日 星期三

Vim 最後一哩路

陸續搞定了 netrw 的一些功能,寫了幾個函數來幫忙,終於對 Vim script 有點感覺了。


雖然回復 cursor 的方法還有點鳥,但目前找不到適合的 event 來監聽,只好勉強先用 Vimresized 頂著先,壞處就是要一個 count 來計算何時該清空變數。


總之,開啟檔案到右邊視窗會觸發第一次,關閉右邊視窗又會觸發第二次,所以當 count == 2 時,我才能放心清空此變數。

現在大概只差寫 Plugin 的經驗了XD

2025/04/17 更新


早上又多檢查了 winnr 的個數,避免開到第三個 Window 後,汙染了原本的 s:MK_sv 變數。

另外,Vimresized 之所以能成功的原因是因為當開了右邊的分割視窗後,此時原本的視窗左邊會長出 scrollbar,故才會有此 Event 的發生。

如果我們去調整 guioption,讓它永遠為空,Vimresized Event 就不再發生了,故我原本的 patch 就不起作用了。

2025/04/18 更新

原來也可以設定 g:netrw_fastbrowse = 2,這樣就不會每次重新抓取目錄列表而導致游標跑掉(離開原本開啟檔案那列),但第一次因為 Buffer 沒有東西,故還是會重刷。

用這個的好處是我可以設定 set guioptions-=L,強制左邊不會有 scrollbar,看起來比較好看。

如果用我原來的 BackToNetrwWindow,則是不能設定沒有左邊 scollbar,不然 Vimresized Event 會失效。

真是有一好沒兩好。

2025/05/12 更新

最後,還是用了自己寫的 netrw,除了工作站無法修改外,公司及家裡的電腦目前都是用自己的 netrw,還是自己的狗糧最好吃XD

2025年4月10日 星期四

Vim 內建 file tree view - Netrw

最近突然發現 Vim 內建的檔案總管,其實已經很夠用了,只要多設定下面幾個全域變數,臨時要瀏覽檔案還算行。

let g:netrw_keepdir = 0
let g:netrw_banner = 0
let g:netrw_winsize = 30
let g:netrw_browse_split = 3

雖然我可以拿到目前 Netrw 指到的檔案名稱,但不太確定要如何操作 Vim 的視窗還是緩衝區來達到 IDE 的介面?


沒關係,我已經比以前的我還進步了XD

不過還是改不了長久以來使用 UltraEdit 的習慣,即使知道快速鍵的使用,但還是很習慣使用方向鍵、delete、backspace。

目前也還沒養成習慣,不編輯時常保持在 Normal Mode。

2025/04/11 更新

今天終於看懂如何改 netrw 顏色了XD


我們只要知道 netrw 的 define 是什麼或是他 link 到那個。

比如說 netrwDir 是 link 到 Directory,故我可以直接改 Directory。

但是像 netrwExe 是 link 到 PreProc,這跟我 Coding 顏色相衝,故我重新定義一個 MKExe,改將 netrwExe link 到 MKExe 即可。

詳情可以參考 vim/syntax/netrw.vim。

2025/04/12 更新

原來 NERDTree 也還好,重點是速度比 netrw 慢(git bash on Windows)。

今天多加了一個視情況改變 statusline 的檢查,看起來舒服多了。


Vim 果然是編輯器之神!

2025/04/16 更新

加入自動增測 winwidth 功能,並可以開啟檔案到右邊視窗,回來也可以順利記住游標位置,目前總算有點樣子了。