2014年3月16日 星期日

case裏default中don't care的使用經驗

以上是有人發現的文章,然後和我討論,建議應該把” default: y=1’bx” 換成是” default: y=1’b0” 或是default: y=1’b1”。反正就是不應該是1’bx,不然會造成系統不穩,或是合成時,會有問題。

” default: y=1’bx” 真的會有問題嗎?
做為一個數位工程師,邏輯推理能力應該是我們自豪的。原英文描述是說在模擬(simulation)時,會有pre-synthesis simulation和post-synthesis simulation的結果不相同(mismatch),所以如果你是想要它相同的話,你應該是把1’bx換成是固定的值,這樣子,每次模擬時,就都會是一樣的。對於這樣子的建議,我同意的它的說法。但是,它的前面有個前提,你的1’bx是會被當成是”don’t care”來處理。我們都知道,don’t care就是不在乎它的結果,甚至每次都是不一樣也沒有關係。所以這樣子的”don’t care”當然會在不同的模擬過程,造成不同的結果。

我們都學過真值表(truth table)

A  fun   B
0
1
0
0
1
1
1
X


上面的truth table表示什麼?當A=1B=1時,我們不在乎它的值是0還是1。那你當然可以把它當成是0來做一個式子,你也可以用1來做另一個式子。那你也真的只是上面有1的結果來做你的式子。但不管哪一種,都會是你要的結果,都是不會錯的。因為會為1的等式必定成立。
上面的verilog 程式也是一樣的。如果這個don’t care是你真的想要的don’t care時,那模擬結果不同時,有差別嗎?答案是沒有;因為你已經把這個會發生的情形考慮清楚,做好所有的處理所以不會讓整個系統發生錯誤。
從上面的英文,都沒有描述到這樣子的做法會讓系統不穩定,或是合成時,會發生問題,以致於netlist是合錯的。
數位工程師最怕的模擬結果是mismatch,但是不是所有的mismatch都是錯誤。要從系統面和真值表中去了解設計的核心。不應該是怕mismatch,所以把所有的mismatch都是當成是錯誤的。這樣子的想法是不對的。

我再舉一個例子,請看下面的verilog的程式。

wire a;
reg [2:0] FSM, FSM_nxt;
always(posedge clki or negedge rstni)
begin
    if(~rstni)
        FSM <=3'b001;
    else
        FSM <= FSM_nxt;
end

always@(*)
begin
    case(FSM)
    3'b001:
        if(a)
            FSM_nxt = 3'b010;
        else
            FSM_nxt = FSM;
    3'b010:
        if(a)
            FSM_nxt = 3'b100;
        else
            FSM_nxt = FSM;
    3'b100:
        if(a)
            FSM_nxt = 3'b001;
        else
            FSM_nxt = FSM;
    default:
        FSM_nxt = 3'bxxx;
    endcase
end

同樣地,default都是有don’t care的描述,但是上面的don’t care並不會讓pre-post simulationpost-simulation產生 result mismatch的問題?原因你知道嗎?因為default 的情況並不會產生,因為FSM的路徑是001->010->100的循環,並不會到別的狀態(例如: 011,110,111,000…等等)。因為FSM不會到達don’t case的狀態,所以不會產生mismatch

那換另一個角度來思考,如果真的跑到don’t case的狀態,那又代表什麼?到目前為止,我遇到的都是表示你的這部份程式的timing violation產生。所以你應該再檢查一次你的synthesis的結果。或許你忽略了這部份的timing,亦或是你的synthesis constrain沒有設定正確,所以這部份的timing被忽視了。不管是哪一個情況,我們都知道don’t care是我們不想發生的情況,所以simulation看到xxx時,你可以很容易就警覺到問題,這對工程師是很有幫助的。

上述的英文讓我們了解到,如果你沒有把所有的情況考思清楚(有用的狀態沒有用的狀態),反而直觀地把所有沒有用的狀態都當成是don’t care時,這時會容易發生英文上所描述的事形發生,這時你就很容易被混淆,而誤會系統是不穩定的。

所以應該是,當你不知道要做什麼時,你不應該用don’t care的語法,因為這會讓你的系統發生你沒有預期的行為。而當你知道你真的是要用don’t care時,而你don’t care語法,這表示你已經考慮到所有的狀態,並讓系統清楚知道要做出什麼的反應和行為,此時,系統就不會發生任何錯誤。

別再為了mismatch而去反抗mismatch;真正去了解為什麼會mismatch,並清楚知道整個系統的運作,會讓你學到更多的事情。







1 則留言:

  1. 一看就是老鳥,完全讚同!
    一些只做官不會做事的人,看到simulation waveform有一堆unknown,
    就覺得沒有安全感,叫你一定要把全部的unknown清掉。
    真的內行的designer都知道,unknown才是最容易找bug的。
    只要waveform裡的unknown都能在該擋住的地方被擋住,
    simulation 結果就是對的。
    如果unknown(don't care)一路穿出到output,要抓也比較好抓。
    硬給它assign一個非unknown的值,debug的時候每條signal都要check,累死!

    回覆刪除