出處:http://bbs.ednchina.com/BLOG_ARTICLE_3013262.HTM
綜合軟件: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電路。