verilog描述組合邏輯一般常用的有兩種:assign賦值語句和always@(*)語句。兩者之間的差別有:
1. 被assign賦值的信號定義為wire型,被always@(*)結構塊下的信號定義為reg型,值得注意的是,這里的reg並不是一個真正的觸發器,只有敏感列表為上升沿觸發的寫法才會綜合為觸發器,在仿真時才具有觸發器的特性。
2. 另外一個區別則是更細微的差別:舉個例子,
wire a;
reg b;
assign a = 1'b0;
always@(*)
b = 1'b0;
在這種情況下,做仿真時a將會正常為0, 但是b卻是不定態。這是為什么?verilog規定,always@(*)中的*是指該always塊內的所有輸入信號的變化為敏感列表,也就是仿真時只有當always@(*)塊內的輸入信號產生變化,該塊內描述的信號才會產生變化,而像always@(*) b = 1'b0;
這種寫法由於1'b0一直沒有變化,所以b的信號狀態一直沒有改變,由於b是組合邏輯輸出,所以復位時沒有明確的值(不定態),而又因為always@(*)塊內沒有敏感信號變化,因此b的信號狀態一直保持為不定態。事實上該語句的綜合結果有可能跟assign一樣(本人沒有去嘗試),但是在功能仿真時就差之千里了。