文章目錄
-
- 前言
- 正文
- 變量可以取什麼樣的值?
- 變量的取值意味着什麼?
- 主要的資料類型
- 其他資料類型
- integer
- time / realtime
- real
- 例子
- Verilog的字元串
- 寫在最後
這是本系列的第三篇博文,依然很基礎,這個系列文章,主要是在沒有其他事情的時候,休閑所作!
如問,有沒有意義,我覺得對我來說是有意義的:
- 首先,對于我寫部落格的條理性來說,是有意義的,以前寫部落格,想到什麼寫什麼,現在需要條理性,也是對知識的一種回顧!
- 其次,對于初學者以及看我部落格的人來說,可以作為一種資料來源用作參考!
- 最後,保持寫作,寫着寫着也許就有思路了呢?
我的微信公衆号: FPGA LAB
本篇部落格講的是Verilog HDL中的資料類型,我最常用的資料類型,無非就三種,reg、wire,integer;其中integer 主要在for 循環中使用。
變量的取值有四種,由于是數字電路,固然是0和1,那第三種、第四種呢?
高阻态 Z以及未知态X。我們在仿真中常見到這兩種狀态,有的時候還弄得人很不爽快!
- 何為高阻态?
高阻态是一個數字電路裡常見的術語,指的是電路的一種輸出狀态,既不是高電平也不是低電平,如果高阻态再輸入下一級電路的話,對下級電路無任何影響,和沒接一樣,類似于引腳懸空,如果用萬用表測的話有可能是高電平也有可能是低電平,随它後面接的東西定。
更詳細的解釋見部落格:
三态之高阻态
FPGA基礎知識極簡教程(8)詳解三态緩沖器
- 何為未知态?
未知态,顧名思義,代表不知道的邏輯值,可以是0也可以是1.
如下總結:
logic value | meaning |
---|---|
represents a logic zero, or a false condition | |
1 | represents a logic one, or a true condition |
x | represents an unknown logic value (can be zero or one) |
z | represents a high-impedance state |
示意圖:
Verilog是一種硬體描述語言,用于描述觸發器,與非門等等一系列的硬體邏輯,是以,其邏輯取值應該在硬體電路中有所對應!
- 邏輯1代表着電源電壓Vdd,邏輯0代表着接地!
- 未知态X可以是0也可以是1,這與布爾代數有所差異,其表示無關!
- 高阻态Z表示未連接配接任何導線,懸空。
主要的資料類型,莫過于reg類型和wire類型,Verilog幾乎可以用這兩種類型通吃了。
- wire類似于将兩個部件在電路闆上連接配接起來:
它用于硬體實體之間的連接配接,是以不會存儲任何值,僅僅起到連接配接元件的作用:
如果需要多個連線,還可以設定wire的位寬,相當于将幾個線捆紮在一起:
wire [3:0] n0;
最後關于wire類型需要注意的是,重複聲明或定義是不合規的。
module design;
wire abc;
wire a;
wire b;
wire c;
wire abc; // Error: Identifier "abc" previously declared
assign abc = a & b | c;
endmodule
- reg類型變量可用于資料的存儲,其可以看做是register的縮寫,也即是寄存器!
如下:
上面的定義,相當于分别定義了一個4bit的存儲空間和一個8bit的存儲空間,可以用來存儲數值。
下圖顯示了,這種變量在硬體電路中的等價:
除了wire以及reg型變量,另一個比較常用的便是integer資料類型了,它表示了32bit的資料寬度,用來存儲整型值,我們在for循環中常常用到它,例如:
for(integer i = 0; i < 10; i = i + 1) begin
//......
end
或者:
integer i = 0;
for(i = 0; i < 10; i = i + 1) begin
//......
end
這兩種類型一般用于仿真,time類型是一個無符号,64bit寬的資料類型,可以用來存儲仿真時間用于調試。
realtime的差別在于僅存儲浮點型資料。
例如:
time end_time; // end_time can be stored a time value like 50ns
realtime rtime; // rtime = 40.25ps
real型變量可以存儲浮點值,可以像整數和reg一樣進行指派。
如:
real float; // float = 12.344 - can store floating numbers
module testbench;
integer int_a; // Integer variable
real real_b; // Real variable
time time_c; // Time variable
initial begin
int_a = 32'hcafe_1234; // Assign an integer value
real_b = 0.1234567; // Assign a floating point value
#20; // Advance simulation time by 20 units
time_c = $time; // Assign current simulation time
// Now print all variables using $display system task
$display ("int_a = 0x%0h", int_a);
$display ("real_b = %0.5f", real_b);
$display ("time_c = %0t", time_c);
end
endmodule
仿真結果:
ncsim> run
int_a = 0xcafe1234
real_b = 0.12346
time_c = 20
ncsim: *W,RNQUIE: Simulation is complete.
字元串在reg中被還原,reg變量的寬度必須足夠大,以容納字元串。字元串中的每個字元代表一個ASCll值,需要1個位元組。如果變量的大小小于字元串,那麼Verilog會截斷字元串的最左邊的位。如果變量的大小大于字元串,那麼Verilog會在字元串的左邊添加0。
// "Hello World" requires 11 bytes
reg [8*11:1] str = "Hello World"; // Variable can store 11 bytes, str = "Hello World"
reg [8*5:1] str = "Hello World"; // Variable stores only 5 bytes (rest is truncated), str = "World"
reg [8*20:1] str = "Hello World"; // Variable can store 20 bytes (rest is padded with zeros), str = " Hello World"
下面舉一個例子進行仿真:
module testbench;
reg [8*11:1] str1;
reg [8*5:1] str2;
reg [8*20:1] str3;
initial begin
str1 = "Hello World";
str2 = "Hello World";
str3 = "Hello World";
$display ("str1 = %s", str1);
$display ("str2 = %s", str2);
$display ("str3 = %s", str3);
end
endmodule
ncsim> run
str1 = Hello World
str2 = World
str3 = Hello World
ncsim: *W,RNQUIE: Simulation is complete.