这是本系列的第三篇博文,依然很基础,这个系列文章,主要是在没有其他事情的时候,休闲所作!
如问,有没有意义,我觉得对我来说是有意义的:
我的微信公众号: FPGA LAB
本篇博客讲的是Verilog HDL中的数据类型,我最常用的数据类型,无非就三种,reg、wire,integer;其中integer 主要在for 循环中使用。
变量的取值有四种,由于是数字电路,固然是0和1,那第三种、第四种呢?
高阻态 Z以及未知态X。我们在仿真中常见到这两种状态,有的时候还弄得人很不爽快!
高阻态是一个数字电路里常见的术语,指的是电路的一种输出状态,既不是高电平也不是低电平,如果高阻态再输入下一级电路的话,对下级电路无任何影响,和没接一样,类似于引脚悬空,如果用万用表测的话有可能是高电平也有可能是低电平,随它后面接的东西定。
更详细的解释见博客:
三态之高阻态
FPGA基础知识极简教程(8)详解三态缓冲器
未知态,顾名思义,代表不知道的逻辑值,可以是0也可以是1.
如下总结:
logic value | meaning |
---|---|
0 | 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是一种硬件描述语言,用于描述触发器,与非门等等一系列的硬件逻辑,因此,其逻辑取值应该在硬件电路中有所对应!
主要的数据类型,莫过于reg类型和wire类型,Verilog几乎可以用这两种类型通吃了。
它用于硬件实体之间的连接,因此不会存储任何值,仅仅起到连接元件的作用:
如果需要多个连线,还可以设置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
如下:
上面的定义,相当于分别定义了一个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.
个人微信公众号:FPGA LAB
知乎:李锐博恩
FPGA/IC技术交流2020