iT邦幫忙

2023 iThome 鐵人賽

DAY 14
0
Software Development

數位 IC 設計起手式系列 第 14

Day 14: 條件判斷與正反器

  • 分享至 

  • xImage
  •  

這篇文章的目標就是實作正反器,但是在開始之前我們要先學習新的 Verilog 語法,這可以有效幫助我們簡化程式碼。

條件判斷

條件判斷在軟體撰寫共分成兩種:if / else, switch / case 。這兩者在 Verilog 中都有支援,只不過 switch / case 會被改為 case 而已。

不論是 if / else 或是 case 都必須在 always block 或 initial block 中使用,因此需要搭配條件判斷的變數都是 reg 型態。

先從 if / else 開始介紹吧!

always @ (*) begin
    if ( <cond 1> ) begin
        // some code
    end
    else if ( <cond 2> ) begin
        // some code
    end
    else begin 
        // some code
    end
end

內部架構和 C 語言的是大同小異,如果 if / else 內部的程式碼只有一行,begin, end 這兩個關鍵字都可以省略。<cond> 代表的是判斷式,我們可以搭配邏輯運算符號來組成判斷式,如:==, ||, &&, ! 等。

再來就是 case 的語法介紹。

always @(*) begin
    case ( <vector> ) 
        <pattern 1>: <code>;
        <pattern 2>: <code>;
        ...
        default: <code>;
    endcase
end

其中,我覺得最彈性的地方是 <vector> 的指定,我們可以透過接合運算子 { } 將數個 vector 結合,這樣可以減少使用 case 的次數。

在 Verilog 中,使用條件判斷要非常仔細,我們必須要考慮所有可能性。如果有一個可能性沒有被包含進去,那麼 Verilog 在合成電路時,有可能會以 latch 去處理個漏洞,電路的功能也許會和我們所學的不太一樣。

DFF in Verilog

先附上 DFF 的真值表,這樣比較方便程式的撰寫!

Clock D Q Q'
Low x Q 不變 Q' 不變
High 0 1 0
High 1 0 1

分別使用 if / elsecase 來完成 DFF 吧。

// Using if / else
module Dff(
    input clk, D,
    output reg Q
);
    always @ (posedge clk) begin
        if (D == 1'b1) Q = 1'b1;
        else Q = 1'b0;
    end
endmodule 
// Using case
module Dff(
    input clk, D,
    output reg Q
);
    always @ (posedge clk) begin
        case (D) 
            1'b1: Q = 1'b1;
            1'b0: Q = 1'b0;
        endcase
    end
endmodule 

Testbench of DFF

DFF 內部邏輯其實很容易完成,但是若要再圖上同時看到時脈和 D, Q ,我覺得就沒有那麼簡單了!
我們可以從兩個方向切入:

  1. 時脈正緣下,Q 確實會跟隨 D 改變。
  2. 當時脈為高位、低位、負緣時,就算 D 有所改變,Q 不會因此有變化。

我綜合了上述兩點產生了一些測資:

module Dff_tb;
    reg clk, D;
    wire Q;

    Dff dff(clk, D, Q);

    initial begin
        $dumpfile("DFF.vcd");
        $dumpvars(0, Dff_tb);

        clk = 1'b0;
        #5 clk = 1'b0;  D = 1'b1;
        #5 clk = 1'b1; D = 1'b1;
        #5 clk = 1'b1; D = 1'b0;
        #5 clk = 1'b0; D = 1'b0;
        #5 clk = 1'b1; D = 1'b0;
        #5 clk = 1'b0; D = 1'b1;
        #5 clk = 1'b1; D = 1'b1;
        #5 clk = 1'b0; D = 1'b0;
        #5 $finish;
    end

endmodule

結果如附圖: (可以檢查兩份檔案輸出的波形圖是否都相同)
https://ithelp.ithome.com.tw/upload/images/20230704/201509823M5GtINxt0.png

時脈正緣共出現在 3 個時間點:10, 25, 35 sec ,可以看到在這些時間點,Q 都有跟隨 D 做出改變。
其他時間點,如:15 sec (時脈高位) D 雖然變為低位,但是 Q 仍維持高位。


上一篇
Day 13: 循序電路之序章
下一篇
Day 15: Blocking & Nonblocking
系列文
數位 IC 設計起手式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言