Try   HackMD

多工器 Mux 常用的描述方法

在處理 if-else 或 Mux 的時候,在 verilog 裡面有下列三種方式:

  1. 三元運算子
  2. if-else
  3. case

三元運算子

使用方式:

assign 輸出 = (條件) ? 符合條件的值: 不符合條件的值;

由於 assign 可以用一行就描述 Combinational Circuit,除了可以描述邏輯之間的關係(and、or、not)外,也可以利用三元運算子,來描述 if-else 的電路,這是一個簡便的表示方式。
注意:

  • 式子左邊的輸出,必須要是 wire 的型別。
  • ? 一定要搭配 : 使用,這兩個一定是成對出現的。
assign out = ( sel_i == 2'b00 ) ? result1 :
             ( sel_i == 2'b01 ) ? result2 :
             ( sel_i == 2'b10 ) ? result3 :
                                  result4 ;

但是建議同學在寫這種超過一種條件式子的時候,最好還是使用 if-else 或 case 來書寫,這樣才比較清楚。只有當式子簡潔簡單的時候才會使用這種三元運算子。例如: assign a = ( b > c ) ? b : c ; 類似這種一行簡單的判斷最大值之類的。

if-else

使用方式:
寫法一:

always @(*)begin
    if( 條件一 )begin
        ...
    end else if( 條件二 )begin
        ...
    end else begin
        ...
    end
end

寫法二

always @(*)begin
    ... //default
    if( 條件一 )begin
        ...
    end else if( 條件二 )begin
        ...
    end
end

在使用 if-else 的時候,有上述兩種寫法,不管是哪種寫法,都一定要將 else 寫出來,以避免產生不必要的 latch (之後課程會提到),造成合成出來的結果不如預期,第二種寫法是先將預設值先寫到 if 的前面,以避免產生 latch,這樣當變數很多的時候,有助於程式碼的理解,且不易混淆,比較好 debug。因此建議同學將 else 的情況放到 if 前面

  • 式子左邊的輸出,必須要是 reg 的型別。
  • 所有可能條件都需要考慮到。
  • if-else 的描述必須包含在 always block 裡面。
always @(*)begin
    out = result4;
    if( sel_i == 2'b00 )begin
        out = result1;
    end else if( sel_i == 2'b01 )begin
        out = result2;
    end else if( sel_i == 2'b10 )begin
        out = result3;
    end
end

case

使用方式:
寫法一:

always @(*)begin
    case(變數)
        值一:
            ...
        值二:
            ...
        ...
        default:
    endcase
end

寫法二:

always @(*)begin
    ... //default
    case(變數)
        值一:
            ...
        值二:
            ...
        ...
    endcase
end

在使用 case 的敘述的時候,必須考慮所有的條件,假設條件裡的變數有三個 bit,則 case 中應該要有 2^3=8 種的 case 全部都寫出來,不然也可以寫某幾種的 case,其他情況寫到 default 裡面,建議同學可以多利用第二種方法,將 default 寫在 case 的前面,這樣當變數很多的時候,有助於程式碼的理解,且不易混淆,比較好 debug。

  • 式子左邊的輸出,必須要是 reg 的型別。
  • 必須要將 default 的情況寫出來。
  • case 的描述必須包含在 always block 裡面。
always @(*)begin
    case(sel_i)
        2'b00:begin
            out = result1;
        end
        2'b01:begin
            out = result2;
        end
        2'b10:begin
            out = result3;
        end
        2'b11:begin
            out = result4;
        end
    endcase
end

最後比較一下三種的描述方式:

  1. 三元運算子 ( ? : ):比較常用來描述單一、簡單的條件式,可以用一行表示的式子。
  2. if-else:用來做比較複雜的條件判斷,比較清楚,增加可讀性和理解。
  3. case:常被用來針對同一個變數的不同值來處理的時候,像是 sequential circuit 的 state,針對同一個變數來判斷的情形。

Home Page