有沒有人有過這種經驗?
覺得自己做了一件事情,做得很好,結果後來才發現根本沒有達到效果?或者更悲劇的是,根本沒有人去確認過它有沒有效,就這樣放著了。
在我的工作經驗裡,這種狀況在 IC 設計裡不是沒有發生過。
上一篇說到,Verilog 是一種描述電路行為的語言。
但寫完了之後,怎麼知道這個電路的行為是不是真的跟我想的一樣?
這個問題,就是用 Verification 來回答。
▋ 踩踏邊界值的重要
我想先分享一個讓我印象很深刻的經驗。
在我的設計工作經驗中,也是我剛接觸硬體程式語言 Verilog 時候,在做一個關於影響處理的題目。
影像處理裡有兩個很重要的訊號,一個叫 hsync,一個叫 vsync,大概就是控制畫面怎麼掃描的。
這個設計看起來是有做對應的處理,功能好像也跑得出來。
但是,有一個問題我當時根本想都沒想過:當這個數值超過設定的邊界,會發生什麼事?( 因為當時真的還太菜 )
就好比說,一個計算機的設計,你測了 1 加 1 等於 2,測了 10 加 10 等於 20,都沒有問題。
但是,有沒有測過,當數字大到超過這個計算機能處理的範圍,會發生什麼事?
在我的認知裡,這就是所謂的 overflow 和 underflow 的問題,也就是呈現的數字已經不能再夠被詳細呈現了。
這個狀況,就是在 Verification 一個很重要需要考量的因素,也是需要特別說道為什麼 Verification 也是一個專業領域的理由。
因為做驗證的,就是得要去想到,這個功能在極端情況下會怎樣。( 當然還有要考慮到很多很複雜的情況 )
▋ Verification 基本的概念
除了邊界值的問題,還有一種狀況讓我覺得很需要被注意。
有些訊號線,設計的時候以為有用,但實際上從來沒有人去測試過它的行為。
就好比說,你設計了一個開關,但是從來沒有人去按過這個開關,確認它到底有沒有作用,那設計這個開關的用意以及目的到底是什麼?來浪費錢的還是來做擺設?
在我的認知裡,最基本的 Verification,就是要確保所有宣告的 input 和 output,都有被 toggle 到,也就是都有被測試到它的行為。
這個動作,在業界 我們會製作一個叫做「 Testbench」的東西,來確保我們以為的,跟別人知道的,認知是一致的。
▋ Testbench 是什麼?
Testbench,就是為了驗證一個功能,而建立的測試環境。
我是這樣想的:有人說他有一套投資策略,說這個策略很有效。
那怎麼確認它有沒有效?
就要找一個實際的市場情境,把這個策略套進去,看看結果是不是真的如他所說。
Testbench 就是這個「市場情境」。
在 Verilog 的世界裡,Testbench 本身也是用 Verilog 寫的,但它的目的不是描述電路的功能,而是模擬各種輸入的情境,然後觀察輸出的結果是不是符合預期。
這就是為什麼我第一次學 Verilog 的時候,會覺得奇怪:為什麼要再寫另外一個 Verilog 來驗證我的 Verilog?
在我現在的理解裡,這兩個 Verilog 的角色是完全不一樣的。
一個是「設計」,一個是「考官」。
▋ 設計者自己的驗證,跟 Verification 工程師的驗證,差在哪裡?
說到這裡,我想說一個在我的觀察裡很重要的概念。
設計者自己做的驗證,比較像是廚師在出餐之前,自己先試吃一口。
我知道我這道菜放了什麼食材、用了什麼步驟,所以我的試吃是有方向的:確認味道有沒有跑掉、火候有沒有到位。
但我試吃的範圍,通常是我自己想到的那幾個點。
Verification 工程師做的驗證,比較像是請一個完全不知道這道菜怎麼做的人來試吃,然後請他說說看有沒有什麼問題。
這個人不知道食譜,所以他的試吃角度可能完全不一樣,他可能會注意到廚師自己沒有注意到的地方。
更完整的做法,是用隨機的方式產生各種不同的輸入,就像是讓一千個不同口味的人來試吃,然後統計有多少人覺得有問題。
在業界,通常會用一個名字叫做 random seed 的方法,也就是用亂數種子產生各種不同的測試情境,確認每一種情境下的結果都符合預期。
▋ Verification 最難的地方是那些出奇不易
說到這裡,我覺得 Verification 最難的地方,是要寫很多測試案例,或是要讓程式碼的每一行都被測試到。
但在我的觀察裡,寫很多測試案例不算是最難的。
最難的,應該是 functional coverage,也就是功能覆蓋率。
我想用一個例子來說明。
先把訊號想像成開關。
一個開關就是開或關。
那假設有一個訊號,它的狀態就只有 0 或 1,兩種情況。
如果有兩個訊號線,各自有開跟關的狀態,那整體來說有幾種組合呢 ?
四種組合。
如果有三個訊號線,就是 2 的 3 次方,八種組合。
但是,實際的設計裡,一條訊號線可能不只有 1 個開關,可能有 10 個開關,那就是 2 的 10 次方,一千多種狀態,只是一條訊號線而已。
再加上多條訊號線之間的組合,以及不同時間點的狀態變化,可能的情況多到根本無法窮舉。
所以 Verification 最難的地方,我認為,是要想清楚哪些「極限值」、哪些「意外的組合」,是設計者當初沒有想到的,但實際使用的時候可能會遇到的。
就好比說,設計一個電梯,你測了一個人進去、兩個人進去、十個人進去,可能都沒有問題。
但是第十一個人呢?
以及有沒有一種情況是,當有人在電梯門快關上的時候,突然把手伸進來,會發生什麼事?
這種「出其不意的操作」,是 Verification 真正要顧慮到的因素。
▋ Verification 是一種對「未知情況」的想像力
說了這麼多,我想用一句話總結這篇的核心。
Verification 不只是確認「已知的功能有沒有做對」,更重要的是想到「還有哪些情況是我沒有想到的」。
設計者知道自己的設計是什麼,所以他的驗證是有方向的。
但越是知道自己設計了什麼,有時候越容易忽略那些「理所當然不會發生」的情況。
在我的觀察裡,一個好的 Verification,不只是讓人相信這個設計是對的,還要讓人深信,就算在別人沒有想到的情況下,它也不會出錯。
下一篇,我打算聊聊 Synthesis,也就是把 Verilog 描述的電路行為,轉換成真實電路元件的過程。
也歡迎大家給我回饋以及想法。
我是 Joker,咱們下回見。













