本系列文將會說明 SystemVerilog UVM 的結構以及前因後果
注意這邊並不會講解如何 SystemVerilog UVM 怎麼使用
而是會介紹一個 Opensourced 類似的工具 - Cocotb
(COroutine based COsimulation TestBench)
https://github.com/potentialventures/cocotb
我們先假設我們要作一個 module
會把 input 的每個 bit 1 輸出兩次, bit 0 輸出一次
Input 5'b01001
依序 output 1,1,0,0,1,1,0
(注意先從 LSB 輸出)
我們寫的 module 假設分兩層
第一層 input 整數,依序 output 1,0,0,1,0
第二層 input 1 bit, output 1~2 bit
中間用 rdy/ack 信號接起來
2-wire, rdy/ack 是很常見、可以用於硬體模組間最簡單的 protocol
發送端把 rdy 跟 data 準備好
直到拿到接受端 ack 才可以換下一筆或是關掉 rdy
根據需求,rdy=0 的時候出現 ack 可以直接無視
或是定義為 protocol error
許多 bus protocol (AMBA, Avalon...) 也只是 2-wire 的變形
一般來說這麼簡單的東西我們應該只要一個 module 就能寫完
不過我們假設每一層是很大很複雜的運算
需要中間每個值的驗證
一般會拿高階語言來作中間驗證
例如用 Python 我們可以大概一分鐘寫出這個行為
def Level1(x, b):
ret = list()
for i in range(b):
ret.append(x&1)
x >>= 1
return ret
def Level2(x):
return [1,1] if x == 1 else [0]
# [1,0,0,1,0]
lv1_result = Level1(9, 5)
# [[1,1],[1,1],[0],[0],[1,1]]
lv2_result = [Level2(x) for x in lv1_result]
接著只要把兩級的結果寫到一個檔案裡面
我們可以實作
- random rdy/ack master (black M)
- 負責 random drive rdy 信號
- random rdy/ack slave (black S)
- 負責 random drive ack 信號
- rdy/ack file initiator (red I)
- 負責觀察 rdy/ack 把資料送到 dat port
- rdy/ack file monitor (red M)
- 負責觀察 rdy/ack 檢查 dat port 資料跟檔案是否一致
然後把這些 module 這樣接
Level 2 也一樣
如果 Level 1, 2 都完成了
我們想驗證兩個接起來會不會動
可以像下面這樣作
可以看到兩個測試中,我們只是重新接線而已
另外,因為 master 一定是配一個 initiator
可以考慮把兩個寫在一起
只要有 C model 或是其他程式語言 dump 的資料
寫 testbench 其實很簡單
- 宣告幾個 master/slave
- 宣告你的 module
- 把檔案塞給 initiator, monitor
- 接線
每個 testbench 都有 87% 像
這時我們只要複製貼以前寫過的 testbench 幾乎就好了
看起來世界非常美好好到想獻上祝福了
但是其實這有兩個問題第一
對於比較大的系統
光是一個檢驗點資料可能隨便就會到 tera-byte 等級
如果是真實系統甚至會要跟外界互動
把這些資料 dump 成 trace 也很麻煩
第二
我們不希望在每個層級都做那麼多的驗證(因為很慢)
現在的方法下,Level 2 是檢查這些
1,0,0,1,0 -> 1,1,0,0,1,1,0
其實常常只要驗證小部份的資料就好了
例如 Level 2 只要驗證這些
1 -> 1,1
0 -> 0
不過現在用的方法下
要作到這件事就要重新生成資料,很不方便
--
為了解決這問題
因此 UVM 這東西就出現了
透過動態的產生資料可以解決上面兩個問題
不過因為我不想打了
所以後面的就留待(二)來說明如何解決這個問題吧
沒有留言:
張貼留言