pretty code

2024年4月23日 星期二

2024 week 17 新玩意

01. Use alias with awk command

之前有提到可以打出下面指令來對數字作加總,一般來說,我們應該都會透過各種 linux 指令只取出數字方便我們後續加工,故 awk 變數應該都是 $1 才對。

awk 'BEGIN {sum = 0} {sum += $1} END {print sum)' xxx_file

但這一長串指令每次都要重打很麻煩,原本想用 alias 來取代,但一直會有問題,後來在網路上看到解法,就是把這些指令拆成 3 個部分即可。

alias sum "awk 'BEGIN {sum = 0} {sum += "\$"1} END {print sum}'"

02. 在 VIM 中善用組合的力量

很多指令都可以合在一起,可以少打好幾個字,舉我最近最常做的事來說,就是要在一個很大的 netlist 檔案中,複製一個 Verilog module。

只要先將游標移到 module 宣告處,依序按下下面鍵即可。

shift + v
/\v^endmodule
y

03. VIM 啟動參數及對應的指令,一般用在開啟多個檔案用

-O vp 垂直分割視窗
-o sp 水平分割視窗
-p tabe 將檔案開起到新分頁

04. Synthesis

將 Synthesis 解釋得很好的一篇文章

05. Yosys proc command

process 是指 yosys 做完 hierarchy 後,初步無法歸類的 RTL statement 都會歸類到這裡,之後再利用 proc command 來處理。

2024年4月10日 星期三

2024 week 15 新玩意

01. awk sum

假設有一文字檔內容如下:

ABC    1
ABC    2

可以用 cat txt_file | awk 'BEGIN {sum = 0} {sum += $2} END {print sum}' 得到加總後數字。

02. VIM vertical column rule

使用下面指令便可以在 8 的位置增加一條垂直線,方便觀看階層資料。

set colorcolumn=8

03. VIM 摺疊文字

選取文字後

zf 摺疊
zo 打開

04. VIM 選取一大片文字

V + xxgg 

05. Synthesis 小疑問

最近在做合成時,發現有些 instance 在做完合成後會被吃掉,連帶原本的 module RTL code 也會一併被移除,雖然覺得因為是這個實體的 output 未被任何 logic 使用,但還是很不確定,最後看到一個寫得很清楚的文章。


結論不只是 output,input 也會有同樣的狀況。

06. tcsh redirect

一般較常用的 bash
ls > file 2>&1

tcsh
ls >& file

2024年4月7日 星期日

D2R 數學機率果然沒騙人

放假本想連工作站做些事,可惜網路一直不通,最後只好放棄XD

一個多月前在小老婆演唱會前將冰法練到 91 級後,想做的大概都做了,想要物品的掉落也只能看人品了?

連假既然無法工作,就來驗證一下喬丹之石的掉落數學機率好了!

網路上有兩個關於喬丹之石掉落的說明:
01. 惡夢安姊掉落機率 1 / 1616。
02. Youtube 有人打安姊掉 100 顆暗金戒出了 4 顆喬丹。

我就以 02 當基準,收集兩次方塊暗金戒總會出 1 顆吧?

一開始 MF 接近 200,後來一直想辦法從各角色倉庫找物品,最後可以湊到 400 MF!

記得是第 5 或是第 6 次還拿到婚戒(不確定是不是剛好遇到邪惡區域才會掉?),不過這個我早就有了。

雖然後來在第 12 顆暗金戒時,就已經湊到 400 MF,但說來奇怪,原本半小時左右會出一顆暗金戒的,後來都要花一個多小時才能打到一顆,最後決定相信感覺,將 MF 降到 27X 後,掉落率開始恢復正常?個人覺得太高的 MF 掉落都變成綠色戒指了?

修正 MF 後,很快的掉落數量來到 17 顆,最後甚至一次掉落兩顆,那時心理就感覺穩了,果然兩顆裡就出現一顆喬丹了XD

感覺最後場次是介於 200 ~ 300 場,D2R 果然是一個訓練耐心的好遊戲呀!

2024年3月30日 星期六

2024 week 13 新玩意

01. VIM 果然好用,以後不需要買第三套 UltraEdit 了

果然學習新東西需要配合環境!

新部門需要在工作站上工作,只能使用 VIM,也趁此機會在本機安裝了 gvim,終於可以好好學習了。

qa   開始錄製巨集到 register a,再按一次 q 結束。
使用 @a 使用巨集,使用 @@ 使用上一次使用的巨集。

:tabe + filename 開啟檔案到另一個分頁,gt 依序切換分頁。
vim -p file1 file2 將檔案分別開啟到分頁上。

:new 水平分割視窗
:vnew 垂直分割視窗

ctrl + w + w 切換視窗

02. Makefile 重複 target

Target1 : dependence2

Target1 : dependence1
        xxxx

執行順序是 dependence1,dependence2,xxxx。

第一個 Target1 只能有相依性選項,該 Target 下不能再執行其他指令。

03. OpenROAD-flow-scripts hierarchy synthesis

當設定 SYNTH_HIERARCHICAL = 1 時,其 Makefile 就是走 02 的寫法,故其實會做兩次 synthesis。

第一次是 synth_hier_report.tcl,第二次是 synth.tcl,除了最前面會設定 hierarchy module(檔案 mark_hier_stop_modules.tcl 在 flow/objects 裡面,跟 abc.constr 同層)。

我目前 trace 的結論是第一次的結果並不會傳遞給第二次,至少從 tcl script 看不出來。

這就是一個很奇怪的點?除非 yosys 結果是分享到記憶體空間,不然我看不到傳遞的地方。

另外,當 abc command 帶 -nocleanup 時,abc-temp-dir 不會被刪除,且資料夾位置會從 /tmp/yosys-abc-xxxxxxx 變成 flow/_tmp_yosys-abc-xxxxxx,裡面會有相關檔案。

design - config.mk 中的 LATCH_MAP_FILE 不設時,當合成的 netlist 有 LATCH,就會以 general 的 $_DLATCH_N_ or $_DLATCH_P_ 代替,並非像 document 說的可以不用設。

constraint 檔案要照文件格式,指令用小寫,不然 period 會無法 parsing 成功。

2024/04/01 更新

終於搞懂 hierarchy 的流程了!

第一次做 yosys 是為了得到第一次 general synthesis 的結果,目的是知道各別 module 的面積,配合 Makefile 裡面的 MAX_UNGROUP_SIZE 變數,當各別 module 面積小於 MAX_UNGROUP_SIZE 時,此 module 會不做 hierarchy synthesis,改做 flatten synthesis,好處是可以得到更好的最佳化結果(相對 synthesis 時間會比較久)。

但因為 MAX_UNGROUP_SIZE 預設值為 0,故其實沒有必要做第一次 synthesis,取而代之是要想辦法得到真實的 module name,因為在設定 "setattr -mod -set hierarchy 1"  時,是使用 yosys 過一手後的 module name。

要得到 module name 也很簡單,hierarchy -check -top top_module 後,使用 stat 或 ls 就可得到。

2024年3月25日 星期一

ImportError: No module named site

新工作似乎脫離不了 GDB?

今天為了找到有問題的 cell library,又要動用 gdb 動態 hook process,指令如下:
gdb attach process_id

然後便可以下 breakpoint,接著使用 c 執行程式。 

但我在啟動 GDB 時就有問題,錯誤訊息如標題。

查了一下,原來 GDB use python for scripting,但是因為工作站有安裝不同的 Python,故會造成版本衝突。

如果新版本 Python 使用 Path or PYTHONHOME 的方式來啟動,把對應的值先拿掉即可。

總之就是要讓 GDB 可以使用到他想用的 Python。

另外,display string 時,又會有下面錯誤:
Python Exception <class 'gdb.error'> There is no member named _M_dataplus.

似乎跟 compiler 有關,詳下面連結。

2024年3月23日 星期六

VIM 常用指令

一般模式

h  左
j 下
k 上
l 右

gg 跳到第 1 行
2gg 跳到第 2 行
G 跳到最後 1 行

H 跳到畫面上方
M 跳到畫面中間
L 跳到畫面下方

zt 將游標處到畫面上方 
zz 將游標處到畫面中間
zb 將游標處到畫面下方

w 跳到下一個單字字首
W 跳到下一個空格後的單字
b 跳到上一個單字字首
B 跳到下一個空格前的單字
e 跳到下一個單字字尾
E 跳到下一個空格後的單字字尾 

{ 跳到上一個段落
} 跳到下一個段落

% 跳到 { } ( ) [ ] 的對應處

d 刪除該行
5dd 刪除 5 行
dw 刪除一個單字
dG 從游標處刪到檔案結尾
dgg 從游標處刪到檔案開頭

yy 複製該行
2yy 複製 2 行
p 在游標下一行貼上
6p 在游標下一行貼上 6 次 

編輯模式

I 在游標字首插入
i  在游標處前一個字元插入
A 在游標字尾插入
a 在游標下一個字元插入
O 在游標上一行字首插入
o 在游標下一行字首插入
S 刪除整行並在字首插入
s  刪除游標字元並插入

指令模式(按下 :  or / 進入)

:n1,n2d  刪除 n1 ~ n2 行
:noh 消除搜尋 pattern 光亮度

:terminal 開啟終端機(ctrl + w + w 可以切換視窗)

/abc 搜尋 abc
/\vpattern 使用 regex
:s/abc/def/g 在游標處用 def 取代 abc
:%sf/abc/def/g 全文取代

可視模式(按下 v or V 進入)

V 表示整行

左右鍵選取字元,上下鍵選取行
aw 表示選取單字

反白後
y 複製
>  向右縮排(假設是 2 ~ 4 行,也可以使用指令 :2,4>
< 向左縮排



.vimrc 設定

syntax on
colorscheme darkblue
set guifont=Courier_New:h12

set nu
set title

set hlsearch

set tabstop=4
set ai
autocmd FileType python setlocal shiftwidth=4 softtabstop=4 expandtab

這週新玩意

01. Verilog 奇怪語法

wire [63:0] data;
wire [7:0] array [7:0];

array [0] = data[0+:8] 前面指的是 base,後面指的是寬度,意思是從 base + width 的範圍,也就是等於 data[8:0]。

這個語法是從 Verilog 2001 開始的,請詳 4.2.1 Vector bit-select and part-select addressing。

02. sed

sed -i "s/abc/def/g" file_name

每次都會忘記,-i 表示要修改檔案,要把所有的 abc 取代成 def。

03. search cell name in cell files

grep -EH 'cell\s*\(\s*\"*sky130_fd_sc_hd__a22o_1' *.lib | sed 's/:\s*cell/ /g' | awk -v var="$PWD" '{print var "/" $1}'

為了在眾多檔案裡找到 cell 位在那個 cell libraries?利用上述語法,我可以得到完整的路徑,便可以貼到我的檔案去做後續的處理。


-EH 要看 grep 版本,我的 WSL 需要這兩個,E 表示 extend,H 表示顯示檔案名,記得工作站不需要。

sed 是把找到的檔案,將檔名跟搜尋 pattern 分開隔出空白。

awk 則是把 $PWD 環境變數傳進去,利用 print 組出完整檔案路徑。

2024年3月17日 星期日

Try Dataflow analyzer of pyverilog

pyverilog 有一個 Dataflow analyzer 的功能,此功能需要 pygraphviz module。

安裝時有一些錯誤,試了一下,按照下面步驟即可成功(網路上的解答適用舊版 pip,pip 23 以後需要這裡的步驟)。

我的環境在 Windows 下,故我要先安裝 graphviz,預設安裝路徑在 C:\Program Files\Graphviz,裡面已經包含相關的 header file and library。

接著打開 "x64 Native Tools Command Prompt for VS 2019",然後輸入底下指令即可。

pip install pygraphviz --config-settings="--build-option=build_ext" --config-settings="--build-option=-IC:\Program Files\Graphviz\include" --config-settings="--build-option=-LC:\Program Files\Graphviz\lib"

另外,example_graphgen.py 100 行有錯,需改成 graphgen.generate(target, walk=options.walk, identical=options.identical, step=options.step, do_reorder=options.reorder, delay=options.delay)

試了一下 OpenROAD-flow 裡面的 gcd.v,把 walk 選項設成 True 後,結果如下圖。

2024年3月15日 星期五

這個星期學到的新東西

01. 當 Python code 裡面有用到很大的記憶體,當你程式離開時,會去釋放這些記憶體,故感覺花 1 分鐘以上才回到 linux shell 是正常的。

02. pyverilog 使用 lex & yacc 的模式來 parsing Verilog 檔案,當檔案很大時,比如 600 多萬行,建立 AST 就要花 20 幾分鐘;同樣的,當你要把 AST 再還原成 Verilog code 時,也是要花個 10 分鐘以上。

那個 600 多萬行的檔案,純用 Python 讀只要 0.6秒,讀一行寫一行到檔案則是 2.X 秒。

03. vim 要使用 regex 搜尋時,某些符號前要打 "\",或是使用 "/\v" 告訴 vim 要使用 regex。

2024/03/21 更新

簡單使用 re 並只 parse instance 及 port arg 的情況下,同一個檔案大概要花 72 秒。 我猜 pyverilog lex 只考慮 netlist 相關的語法下,應該可以更快沒錯。

2024年3月9日 星期六

正規表示法未解之謎

我有一段簡化過的文字如下,@ 代表空格字元:

@@@@module@ANDGATE@(
@@ANDGATE@gate1@(.A1(A1),@.A2(A2),@.Z(Z));
@@@@module@ORGATE@(
@@ANDGATE@gate1@(.A1(A1),@.A2(A2),@.Z(Z));
@@ORGATE@gate1@(.A1(A1),@.A2(A2),@.Z(Z));


原本打算使用下面的 Regex 來取出各 cell init instance 那行。 

^\s+[^m].*GATE

但因為 \s+ 不會抓最大數量,故 @@@@module 前面 4 個字元也會符合 ^\s+[^m],對正規表示來說前 3 個空白符合 \s+,第 4 個空白符合 [^m] (應該說 Regex 原本用 4 個空白匹配 \s+,但因為發現這樣解讀這行就不滿足了,Regex 為了要盡可能做匹配,故使用了回溯技巧)。

目前還不知道要如何使用 [^m] 這種否定語句,只能使用 ^\s+(AND|OR) 來抓出我要的,但前提是我必須知道所有 case?

一個有 600 多萬行的文字檔,用正面表列確實沒那麼好用,我的正規表示法功力還有待加強XD

2024年2月26日 星期一

cell library parser

看了好多天的文件,有點阿雜XD

因為工作站無法自行安裝 Python module,想要檢查 cell library 的目標一直無法達成。今天簡單用 regex + stack + FSM 寫個 parser,parser 部分花了 3 個小時,另外又花了半小時將之前用 Python module 寫的 code 複用。

兩個 Open cell library 檔案加一個 TSMC cell library 看起來都可以 parsing,只是不知為何工作站 parsing TSMC 69 M 大小的檔案大概要花 7 秒鐘,可能是先 parsing 到 list 再從 list iterate loop 花了一點時間,但整體還算滿意。

有機會還是要學 Compiler 使用正統的 parsing 方式,雖然要利用第三方工具,但之後擴充應該比較容易?

目前 cell library 這樣的格式看起來擴充性還行?

2024年1月17日 星期三

神奇的正規表示法

每次都覺得正規表示法很神奇,換了一個工具就有該工具的眉角要注意!

最近沒有意外應該都會在 Linux 下工作,sed 是一個很常用的工具,常用來取代檔案的字串用。

sed 和 grep 一樣,有分 BRE 和 ERE 兩種模式,-E 則代表使用 ERE。

昨天看到一篇文章,剛好有個範例可以練習,沒想到一直試不成功。

下午在寫完簡報後,突然福至心靈的解決了,順便記錄一下。

有一個檔案內容如下:

<html><head><title>Hello World</title>
<body>Welcome to the world of regexp!</body></html>

想要使用 sed 取出非 HTML tag 的內容。

原本是使用 BRE 無法成功
sed -n 's/<.*>\([a-zA-Z !]+\)<\/.*>/\1/p' fileName

改使用 ERE 即可
sed -En 's<.*>([a-zA-Z !]+)<\/.*>/\1/p' fileName

Note: 上面的 Rex 似乎要把整行都明確表示出來,否則達不到我們要的效果

2024年1月13日 星期六

星星之火,可以燎原

程式 Bug 就是如此神奇?

快兩個月前發現 Daily Money 因為資料庫筆數已經突破 20,179 筆,導致明細報表無法在既定的時間內完成而產生 ANR。

當時因為忙於交接,故只用最快的方式找到錯誤的地方做點小 patch,但因為沒有仔細研究,所以留下了一個小 Bug,在切換月份的時候日期就會整個錯亂XD

原來 currentDate 是有意義的,當按 Prev() or Next() 時,currentDate 會變動,currentEndDate 也會隨之變動,故我不能重新計算 currentDate 的值!

當初只改 4 行以為解決了 ANR 問題,沒想到也留下一個月報表及年報表的錯誤,果然星星之火可以燎原,雖然現在只要 2 行就可修復。

簡單做了點驗證,希望兩個月後不要再發生其他問題XD

目前資料筆數來到 20,450 筆。


2024/01/15 更新

稍微再多看一點 code,釐清了幾個地方。

totalMode = 1 表示是資產負債表。

currentDate 會在按下 Prev() or Next() or Today() 時改變,接著呼叫 reloadData(),在這裡會重新計算 currentStartDate 和 currentEndDate,也是在這裡面依 totalMode 決定 currentStartDate 是不是 null。

故嚴格來說,兩個月前為了解決 ANR,應該把 patch 改在這裡,比較符合原開發者的意思。

2024年1月4日 星期四

Some tips in Makefile - 003

01. $(XXX:.lib=_.lib)

WRAP_LIBS = abc.lib def.so
$(info $(WRAP_LIBS:.lib=_.lib))

將 XXX 變數裡的 ".lib" 字串變成 "_.lib"

$(patsubst %.lib,%_.lib, $(WRAP_LIBS)))

也可以用 patsubst 函數,但 %_.lib 前面不能有空格,否則被取代的字串前面會多一個空格。