在處理 if-else 或 Mux 的時候,在 verilog 裡面有下列三種方式:
使用方式:
assign 輸出 = (條件) ? 符合條件的值: 不符合條件的值;
由於 assign 可以用一行就描述 Combinational Circuit,除了可以描述邏輯之間的關係(and、or、not…)外,也可以利用三元運算子,來描述 if-else 的電路,這是一個簡便的表示方式。
注意:
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 ; 類似這種一行簡單的判斷最大值之類的。
使用方式:
寫法一:
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 前面。
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
使用方式:
寫法一:
always @(*)begin
case(變數)
值一:
...
值二:
...
...
default:
endcase
end
寫法二:
always @(*)begin
... //default
case(變數)
值一:
...
值二:
...
...
endcase
end
在使用 case 的敘述的時候,必須考慮所有的條件,假設條件裡的變數有三個 bit,則 case 中應該要有 2^3=8 種的 case 全部都寫出來,不然也可以寫某幾種的 case,其他情況寫到 default 裡面,建議同學可以多利用第二種方法,將 default 寫在 case 的前面,這樣當變數很多的時候,有助於程式碼的理解,且不易混淆,比較好 debug。
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
最後比較一下三種的描述方式: