%備查
Cummings經典論文閱讀筆記,第一篇,論文是A Proposal To Remove Those Ugly Register Data Types From Verilog.
reg還是wire?
在給變量賦值時,什么時候用register類型什么時候用net類型,這個問題經常犯迷糊。
net型,線網型,主要有以下類型: wire、tri、supply1、supply0、wor、trior等等等等,wire是最主要的類型。
register型,寄存器型,主要有reg、integer、real、time、realtime等,reg用得最多,integer在testbench里面會用到。
怎么使用這兩種類型? 先看兩段Verilog代碼
module and1 (y,a,b);
output y;
input a,b;
wire y;
assign y = a & b;
endmodule
和
module and2 (y,a,b);
output y
input a,b;
reg y;
always @(a or b)
y = a & b;
endmodule
這兩段代碼都會生成一個兩輸入與門,但第一個例子用的是wire,使用的是連續賦值;第二個例子用reg,為過程賦值。可以把連續賦值理解為,y=a&b這個語句是一直在執行的,y一直被觸發更新;而過程賦值理解為,當a或b其中有一個有變化時,y=a&b這個語句才被觸發執行,當a或b不變時,語句不執行,y保持不變,這也是為什么在always敏感量列表里面要把輸入的變量寫全。將第一個例子里的wire y;
改成reg y;
或者將第二個例子里的reg y;
改成 wire y;
編譯器都會報錯。因此給出以下規定:
在過程塊中被賦值的變量,一律設為register型,非過程塊中被賦值的變量一律為net型。
遵循這個法則,在使用的時候必定不會出錯
變量聲明時要寫全
- 任何賦值語句左邊的不是輸入輸出端口的變量,都需要被聲明。
- 輸入端口的wire型變量可以不聲明
- reg型的變量必須聲明
以下是合法的聲明
output reg y;
output y;reg y;
module (output reg y; input a, b, c);
變量聲明時位寬要寫清楚
很多變量在聲明的時候沒有寫清楚位寬,被當做總線在用,如果不說明位寬,例如下面代碼中的tmp默認是一位寬。編譯時并不會報錯,但寫testbench進行仿真時,只有a[0]被賦給tmp,而y[7:1]則全部被拉到0;因此在變量聲明過程中,最好將變量的位寬寫清楚以免出現剛剛的問題。wire [7:0] tmp;
module inverter8 (y, a);
output [7:0] y;
input [7:0] a;
wire tmp;
assign tmp = ~a;
assign y = tmp;
endmodule