Verilog語言數據類型基礎教程
線網(wire)
Verilog 最常用的 2 種數據類型就是線網(wire)與寄存器(reg),其餘類型可以理解為這兩種數據類型的擴展或輔助。
wire 類型表示硬件單元之間的物理連線,由其連接的器件輸出端連續驅動。如果沒有驅動元件連接到 wire 型變量,缺省值一般為 "Z"。舉例如下:
實例
wire interrupt ;
wire flag1, flag2 ;
wire gnd = 1'b0 ;
線網型還有其他數據類型,包括 wand,wor,wri,triand,trior,trireg 等。這些數據類型用的頻率不是很高,這裡不做介紹。
寄存器(reg)
寄存器(reg)用來表示存儲單元,它會保持數據原有的值,直到被改寫。聲明舉例如下:
實例
reg clk_temp;
reg flag1, flag2 ;
例如在 always 塊中,寄存器可能被綜合成邊沿觸發器,在組合邏輯中可能被綜合成 wire 型變量。寄存器不需要驅動源,也不一定需要時鐘信號。在仿真時,寄存器的值可在任意時刻通過賦值操作進行改寫。例如:
實例
reg rstn ;
initial begin
rstn = 1'b0 ;
#100 ;
rstn = 1'b1 ;
end
向量
當位寬大於 1 時,wire 或 reg 即可聲明為向量的形式。例如:
實例
reg [3:0] counter ; //聲明4bit位寬的寄存器counter
wire [32-1:0] gpio_data; //聲明32bit位寬的線型變量gpio_data
wire [8:2] addr ; //聲明7bit位寬的線型變量addr,位寬范圍為8:2
reg [0:31] data ; //聲明32bit位寬的寄存器變量data, 最高有效位為0
對於上面的向量,我們可以指定某一位或若幹相鄰位,作為其他邏輯使用。例如:
實例
wire [9:0] data_low = data[0:9] ;
addr_temp[3:2] = addr[8:7] + 1'b1 ;
Verilog 支持可變的向量域選擇,例如:
實例
reg [31:0] data1 ;
reg [7:0] byte1 [3:0];
integer j ;
always@* begin
for (j=0; j<=3;j=j+1) begin
byte1[j] = data1[(j+1)8-1 : j8];
//把data1[7:0]…data1[31:24]依次賦值給byte1[0][7:0]…byte[3][7:0]
end
end
Verillog 還支持指定 bit 位後固定位寬的向量域選擇訪問。
- [bit+: width] : 從起始 bit 位開始遞增,位寬為 width。
- [bit-: width] : 從起始 bit 位開始遞減,位寬為 width。
實例
//下面 2 種賦值是等效的
A = data1[31-: 8] ;
A = data1[31:24] ;
//下面 2 種賦值是等效的
B = data1[0+ : 8] ;
B = data1[0:7] ;
對信號重新進行組合成新的向量時,需要借助大括號。例如:
實例
wire [31:0] temp1, temp2 ;
assign temp1 = {byte1[0][7:0], data1[31:8]}; //數據拼接
assign temp2 = {32{1'b0}}; //賦值32位的數值0
整數,實數,時間寄存器變量
整數,實數,時間等數據類型實際也屬於寄存器類型。
整數(integer)
整數類型用關鍵字 integer 來聲明。聲明時不用指明位寬,位寬和編譯器有關,一般為32 bit。reg 型變量為無符號數,而 integer 型變量為有符號數。例如:
實例
reg [31:0] data1 ;
reg [3:0] byte1 [7:0]; //數組變量,後續介紹
integer j ; //整型變量,用來輔助生成數字電路
always@* begin
for (j=0; j<=3;j=j+1) begin
byte1[j] = data1[(j+1)8-1 : j8];
//把data1[7:0]…data1[31:24]依次賦值給byte1[0][7:0]…byte[3][7:0]
end
end
此例中,integer 信號 j 作為輔助信號,將 data1 的數據依次賦值給數組 byte1。綜合後實際電路裡並沒有 j 這個信號,j 隻是輔助生成相應的硬件電路。
實數(real)
實數用關鍵字 real 來聲明,可用十進制或科學計數法來表示。實數聲明不能帶有范圍,默認值為 0。如果將一個實數賦值給一個整數,則隻有實數的整數部分會賦值給整數。例如:
實例
real data1 ;
integer temp ;
initial begin
data1 = 2e3 ;
data1 = 3.75 ;
end
initial begin
temp = data1 ; //temp 值的大小為3
end
時間(time)
Verilog 使用特殊的時間寄存器 time 型變量,對仿真時間進行保存。其寬度一般為 64 bit,通過調用系統函數 $time 獲取當前仿真時間。例如:
實例
time current_time ;
initial begin
#100 ;
current_time = $time ; //current_time 的大小為 100
end
數組
在 Verilog 中允許聲明 reg, wire, integer, time, real 及其向量類型的數組。
數組維數沒有限制。線網數組也可以用於連接實例模塊的端口。數組中的每個元素都可以作為一個標量或者向量,以同樣的方式來使用,形如:<數組名>[<下標>]。對於多維數組來講,用戶需要說明其每一維的索引。例如:
實例
integer flag [7:0] ; //8個整數組成的數組
reg [3:0] counter [3:0] ; //由4個4bit計數器組成的數組
wire [7:0] addr_bus [3:0] ; //由4個8bit wire型變量組成的數組
wire data_bit[7:0][5:0] ; //聲明1bit wire型變量的二維數組
reg [31:0] data_4d[11:0][3:0][3:0][255:0] ; //聲明4維的32bit數據變量數組
下面顯示瞭對數組元素的賦值操作:
實例
flag [1] = 32'd0 ; //將flag數組中第二個元素賦值為32bit的0值
counter[3] = 4'hF ; //將數組counter中第4個元素的值賦值為4bit 十六進制數F,等效於counter[3][3:0] = 4'hF,即可省略寬度;
assign addr_bus[0] = 8'b0 ; //將數組addr_bus中第一個元素的值賦值為0
assign data_bit[0][1] = 1'b1; //將數組data_bit的第1行第2列的元素賦值為1,這裡不能省略第二個訪問標號,即 assign data_bit[0] = 1'b1; 是非法的。
data_4d[0][0][0][0][15:0] = 15'd3 ; //將數組data_4d中標號為[0][0][0][0]的寄存器單元的15~0bit賦值為3
雖然數組與向量的訪問方式在一定程度上類似,但不要將向量和數組混淆。向量是一個單獨的元件,位寬為 n;數組由多個元件組成,其中每個元件的位寬為 n 或 1。它們在結構的定義上就有所區別。
存儲器
存儲器變量就是一種寄存器數組,可用來描述 RAM 或 ROM 的行為。例如:
實例
reg membit[0:255] ; //256bit的1bit存儲器
reg [7:0] mem[0:1023] ; //1Kbyte存儲器,位寬8bit
mem[511] = 8'b0 ; //令第512個8bit的存儲單元值為0
參數
參數用來表示常量,用關鍵字 parameter 聲明,隻能賦值一次。例如:
實例
parameter data_width = 10'd32 ;
parameter i=1, j=2, k=3 ;
parameter mem_size = data_width * 10 ;
但是,通過實例化的方式,可以更改參數在模塊中的值。此部分以後會介紹。
局部參數用 localparam 來聲明,其作用和用法與 parameter 相同,區別在於它的值不能被改變。所以當參數隻在本模塊中調用時,可用 localparam 來說明。
字符串
字符串保存在 reg 類型的變量中,每個字符占用一個字節(8bit)。因此寄存器變量的寬度應該足夠大,以保證不會溢出。
字符串不能多行書寫,即字符串中不能包含回車符。如果寄存器變量的寬度大於字符串的大小,則使用 0 來填充左邊的空餘位;如果寄存器變量的寬度小於字符串大小,則會截去字符串左邊多餘的數據。例如,為存儲字符串 "run.runoob.com", 需要 14*8bit 的存儲單元:
實例
reg [0: 14*8-1] str ;
initial begin
str = "run.runoob.com";
end
有一些特殊字符在顯示字符串中有特殊意義,例如換行符,制表符等。如果需要在字符串中顯示這些特殊的字符,則需要在前面加前綴轉義字符 \ 。例如下表所示:
其實,在 SystemVerilog(主要用於 Verilog 仿真的編程語言)語言中,已經可以直接用關鍵字 string 來表示字符串變量類型,這為 Verilog 的仿真帶來瞭極大的便利。有興趣的學者可以簡單學習下 SystemVerilog。
以上就是Verilog語言數據類型基礎教程的詳細內容,更多關於Verilog數據類型的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- Postgresql的pl/pgql使用操作–將多條執行語句作為一個事務
- PostgreSQL數據庫中匿名塊的寫法實例
- Verilog 設計方法及流程詳解
- C++實現中值濾波的示例代碼
- Golang 獲取文件md5校驗的方法以及效率對比