Verilog-FPGA硬體電路設計之一——if語句優先順序問題
綜合軟體:Quartus II
一、有優先順序的if語句
if..else if.. else if … …else..語句中是有優先順序的,第一個if具有最高優先順序,最後一個else優先順序最低。Quartus綜合出的RTL圖認為,最高優先順序的電路靠近電路的輸出,輸入到輸出的延時較短;最低優先順序的電路遠離輸出端,輸入到輸出的延時較長。
module single_if_late(A, C, CTRL_is_late, Z);
input [6:1] A;
input [5:1] C;
input CTRL_is_late;
output Z; reg Z;
always @(C or A or CTRL_is_late)
// late arriving signal in if condition
if (C[4] == 1'b1 && CTRL_is_late == 1'b0) Z = A[4];
else if (C[1] == 1'b1) Z = A[1];
else if (C[2] == 1'b0) Z = A[2];
else if (C[3] == 1'b1) Z = A[3];
else if (C[5] == 1'b0) Z = A[5];
else
Z = A[6];
endmodule
RTL圖:
二、無優先順序if語句
幾個無優先順序的if語句在組合邏輯電路中,採用阻塞賦值和非阻塞賦值效果一樣。但是無優先順序if語句設計組合邏輯電路,並非就是沒有優先順序,而是優先順序按照阻塞賦值的先後順序(因為硬體電路對同一個訊號做不同的處理總會有先後順序),一個always塊中的最後一個if語句具有最高優先順序。(所有if語句中必須操作同個一個reg訊號)
always @(C or A or CTRL_is_late)
// late arriving signal in if condition
begin
Z = A[6];
if (C[4] == 1'b1 && CTRL_is_late == 1'b0) Z = A[4];
if (C[1] == 1'b1) Z = A[1];
if (C[2] == 1'b0) Z = A[2];
if (C[3] == 1'b1) Z = A[3];
if (C[5] == 1'b0) Z = A[5];
end
注: always塊中 賦值的訊號,必須定義為 reg型,但是並不等同於硬體電路產生一個暫存器。純組合邏輯電路中,的reg訊號,等同於wire連線。
三、無優先順序的if語句,如何讓條件全部覆蓋呢?
1、可以像上述程式,直接在所有的if語句之前加上一個最低優先順序的值,也可以是復位值。
2、可以放在第一個if後面的else裡面。
3、要注意被阻塞的情況。
下面就是個阻塞的例子:
always @(C or A or CTRL_is_late)
// late arriving signal in if condition
begin
//Z = A[6]; //可以放在此位置
if (C[4] == 1'b1 && CTRL_is_late == 1'b0) Z = A[4];
//else Z = A[6]; //可以放在此位置
if (C[1] == 1'b1) Z = A[1];
if (C[2] == 1'b0) Z = A[2];
if (C[3] == 1'b1) Z = A[3];
else Z = A[6]; //放在此處,上面的if被阻塞
if (C[5] == 1'b0) Z = A[5];
end
生成的RTL圖如下:
Z = A[6];可以放在第一個if的else中(因為之前無賦值語句,所以不會被阻塞),但不能放在其他的if後面。那麼放在何處會產生阻塞的情況?
1、假如放在第4個if後面的else 裡面,那麼前面3個if就被阻塞了,因為第4個的else中已經包含了前三個if語句的條件,要時刻記住always塊中的阻塞賦值生成的組合邏輯電路是按照順利執行的。 既然是按照順序,那第4個if的else裡面已經包含了前面的if條件,那麼前面條件就沒有意義,而綜合軟體在進行綜合時,就將前面3個if語句優化掉,即不會生成對應的電路。同樣道理,放在第一個if後面的else中是可以的。
2、不加else判斷,直接放在某兩個if語句之間,同樣會阻塞此語句之前的所有if語句。
3、如果無此語句,那麼條件覆蓋不完全,產生鎖存,如下圖生成的RTL電路。