pretty code

2024年8月25日 星期日

Verilog 里程碑

Verilog 真的是很神奇的一門語言!

有時候覺得懂了,有時候卻又覺得什麼都不懂!至少無法像我會的其他程式語言一樣,可以隨心所欲的拿它來解決任何問題。

HDLBits 是一個很好的網站,可以拿它來學習 Verilog,但它有一些缺點,我們無法看到它的 Testbench,所以有時 debug 會有點困難,不過想想 leedcode 也是如此,似乎也很正常?

另外,它其實是會跑 Synthesis,故它其實是用合成出來的 netlist 來跑 Testbench。換句話說,如果寫出來的 Verilog 有問題,則有可能會跑不過 post-synthesis simulation。


這題我覺得是一個學習 Verilog 的里程碑,至少對我來說是如此。

照它題意,它希望你用前幾題學到的技巧,來解決這題,也就是將前幾題的電路用在此處。

但我一直無法順利用小電路來解決此一道題,我甚至想寫 3 個 module 來解此問題,其中最後兩個訊號,我感覺是一樣的意思,故想用同一個 module 來解題,換句話說,我的 top_module,就只是 initial 4 個實體罷了。

雖然可以用 iverilog 跑成功,但是在 HDLBit 就是會錯在 130 ns 的時間點,在知道 HDLBits 是用 netlist 跑合成後,我甚至用 DC 試跑合成,果然我的 netlist 用 ncverilog 也會跑出問題,問題是出在 DC 會報 time loop warning,故它在 3 個 cell 處會忽略 timing arc,我在 dump waveform 會一直無限膨脹檔案大小,卡在 100 ns 處,感覺是我組合邏輯哪邊有問題?


如果我放棄使用小電路方式來解題,改在 top_module 用 FSM 寫出所有的 code,就可以順利通過 HDLBits 的 Testbench。

我想讓 shift_ena、counting、done 都委由 submodule 來設定,但這會有 timing 問題,有時候為了滿足 timing 我甚至會在 submodule 改用組合邏輯提早一個 T 將訊號送出,好滿足下一個 submodule 的 timing。

先不說這樣設計對不對,但我還是想用這樣的方式來解決這一道題目,說它是我學習 Verilog 的里程碑還真不為過。

想當年我初學程式以及使用 Keil C 撰寫 8051 也都是卡在某個地方,後來意外打通之後,世界突然就變輕盈了,真希望趕快打通這裡。

2024/08/25 更新

忘記在哪個 github 看到,有人確實是用兩個電路來解決此題,recognizer and shifter,但是他是在 top_module 統一控制 output 訊號。

目前只知道,HDLBits 會故意在不同階段亂送某階段需要觀察的訊號,但我還是想不通我的 130 ns 錯在哪裡?

2024/08/26 更新

我的第一個 submodule pattern 是用來捕捉 1101 訊號用,故其餘的 submodules 都是靠他往下走,所以我需要讓 pattern 不要被 data 訊號影響,這是我錯誤的第一個點,也就是說整個電路未完成前(未收到 ack 前),我的 pattern 應該要讓他一直處在 reset 狀態才對。

其餘的錯誤就是其他 submodules 忘記在 END state 回到 IDLE 階段。


雖然目前暫時解決了,但為了配合時序圖,提早改變 output 訊號感覺還是很怪?

我覺得要不就是我不能這樣劃分 submodule,不然就是我的 verilog 寫法還是哪邊觀念不對。

2024/08/27 更新

今天看 1500 spec 時,文件也有提到需讓待測 core 視情況處在穩定狀態(reset),看起來這是用 Verilog 描述電路時的一個重要關鍵,就像我們純軟在 task 做完時,會 reset 變數一樣!

補上 gtkwave 訊號 configuration,之後有空再來繼續改進此電路XD

橘色劃線的訊號就是為了配合時序控制下一個電路而提早 1T 改變的回饋觸發訊號。


2024/08/29 更新

看 1500 spec 突然想到,米利型 FSM 的輸出不只要看 state 也會看輸入,我的 stop_module 頗有這樣的味道在?done_counting or ack 就是我要配合的輸入。

另外在看同事 wrapper demo code 時,發現該同事會用很多 assign 語法,甚至還看到他不直接 posedge clk 而是改用 assign 語法將 wire 搭配一些條件判斷將 clk 指派給該 wire,之後反而直接用 posedge wire_name?

原來我沒看過的 Verilog code 還真多,雖然還沒深入探討,但應該是為了 timing 或是為了縮短減少測試時間?應該吧?

2024/08/30 更新

昨天忘記補充,摩爾型 3 段式 FSM 的 output logic,我有看到用組合的也有看到用循序的。

我覺得比較合理的應該是用組合邏輯,但我有看到一個比較合理的說法,為了避免組合邏輯 path 過長影響 timing,所以會多敲一級改用循序邏輯。

不過在我這邊的 case 就不適用,因為我的 timing 已經太慢,用循序會再多慢上 1T。

沒有留言: