pretty code

2024年8月17日 星期六

2024 week 33 新玩意

01. Synthesis area improvement

這兩個禮拜除了研究 Verilog race condition 現象外,其餘時間都在包 SRAM wrapper!

部門資深同事著實太忙,想說自己來研究一下好了,Width 還算簡單,但 Depth 就需要稍微想一下,第一版出來後,對照時序圖寫了 testbench,也確認功能有合乎預期。

這星期再一次 review 同事那包 RTL code 才發現,有一個名為 dual port 的 FIFO SRAM,其真實行為居然是 1R1W,故只好再包另外一種 SRAM wrapper。

這個 wrapper 比較特別,有設計 bypass,但居然是 sequential logic?我唯一想到的就是不要太早反應 SRAM 吐回去的 data?不然正常來說,不管是調整 Width 或是 Depth,我們應該都用 combinationl logic 即可。

除了寫 testbench 外,也順便用 DC 跑 Synthesis,post-synthesis simulation 也是正常。

在等待工作站 code ready 的空檔,順便研究一下 RTL code 與面積的關係。

我需要的 SRAM wrapper 跟真實的 SRAM 資訊如下:

DP 4096X96 ( SP512X32 )
DP 1024X96 ( SP512X32 )
2P 1024X64 ( 2P512X32 )

1 和 2 其實是相關的,故我一開始是用 2 的 module 再包一層,但這樣面積會比較大,拆成 8 顆 512X96 後,面積就改進了。

一些取餘數跟 Address 位址一開始沒想到的 code,在改正後,面積居然沒變,看起來 DC 有一定的功力,知道如何優化。

但隨著 code 不斷再精簡(通常來說,RTL code 越多,其實合出來的 cell 也就越多),最後兩種 wrapper 面積分別可以減少 300 和 200 左右。

我用的 Cell Library INV 的某 cell 面積大概是 1.29,其他一些小 cell 約略是 0.29 左右,基底的 SRAM 以 1P 來看則約莫是 5000 多一點。

過程中還發生了小插曲,因為被 KB5041578 事件搞了,最後一版的 RTL code 還未跑 simulation,故等到下午 IT 處理後補跑才發現資料都是錯的,由於這裡沒有用 Git,工作站空間也很吃緊,故我也沒建 local git,因改動的東西確實太多(第一版 code 真的很差,雖然可讀性比較好,但應該是我還用 SW 思維寫 code 的緣故,之後應該會慢慢習慣),只好一層一層 wrapper 檢查回來,但也很快地找到原因。

我發現組合邏輯善用 bit operation 後,大部分可以有效減少面積,但撰寫時就要特別注意資料寬度是否一致。

由於同事那包 RTL code,其 SRAM port 和 active signal 都跟我用的 Cell Library 不同,考量這只是中繼 wrapper(最終還是要用 Memory Compiler 重新產生,只是什麼軟體都要 License,目前部門還沒有相關 License 可用),故把 difference 直接改在最底層的 module code 中。

原本的 code:

localparam WIDTH = 32;

input WEB;

if (WEB)
    BWEB = 32'h00000000;
else
    BWEB = 32'hFFFFFFFF;

改進後:

BWEB = (~(32'h00000000 | WEB)

正確的 code:

BWEB = (~(32'h00000000 | {WIDTH{WEB}};

只是 or 操作的長度不對,結果就天差地遠XD

02. testbench simulation

雖然知道了 Verilog race conditon,也看了Clifford E. Cummings 大神的幾篇論文,但對於 testbench 設值的時間點還是不知道有沒有一般公認的標準可供遵循?大神的論文雖然有些建議,但我還是覺得看 Spec 寫 testbench 還是最適當?

寫 testbench 時,我們很容易讓 clk 和 data 在同一個 timing 中更改,這其實要看 active event region 被 simulaor 取出執行的順序,故結果不一定跟你想的一樣?

這也是為什麼 VCS 有一個 deraceclockdata 的 flag 可設,雖然應該要使用者自行避免才對。

我自己感覺 iverilog 行為是這樣?

testbench 中設定的值,不管是 clk or data,sensitivity list 的 signal,就是你在另外 module 中會用 if 判斷的,iverilog 會先設值,接著是 clk,最後才是 data,就是 RHS 的 signal。

順帶一提,要 trace iverilog 的 code 應該要從 vvp 和 tgt-verilog 的資料夾開始,當初稍微一喵的感覺是這樣?

不過在前項 SRAM wrapper 的研究中,TSMC SRAM 確實是在 postedge 前,address 和 data 就要 ready,我最早版本的 SRAM testbench 也是這樣設值,差別在 TSMC Spec 看起來最好不管是讀或寫,最好都保持 2 個 T 後,第 3 個 T 才繼續下一動操作,雖然我用他們的 verilog code 跑 testbench 用原始版本 1 個操作使用 1 個 T 也是正常?

我目前的結論是還是看時序圖寫 testbench 最準。

希望等到越來越有經驗後,能夠回過頭來給個最後結論。

由於 Verilog 及相關知識都是自行上網學習,也不知道自己看的方向是否正確?

沒有留言: