pretty code

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