Verilog语言中数据类型的主要目的是表示数据存储元素(如触发器中的位)和传输元素(如连接在逻辑门和顺序结构之间的导线)。
变量具有什么值?
几乎所有数据类型只能具有以下四个不同的值之一,real和event数据类型除外。
represents a logic zero, or a false condition
represents a logic one, or a true condition
represents an unknown logic value (can be zero or one)
represents a high-impedance state
0 | 表示逻辑零或错误条件 |
---|---|
1 | 代表逻辑1或真实条件 |
x | 不定态,0或1 |
– | – |
z | 代表高阻抗状态 |
下图显示了如何在时序图和仿真波形中表示这些值。 大多数模拟器使用此约定,其中红色代表X,橙色代表高阻抗或Z。
Verilog值集意味着什么?
由于Verilog本质上用于描述诸如触发器之类的硬件元素以及诸如NAND和NOR之类的组合逻辑,因此它必须对硬件中的价值体系进行建模。 逻辑一表示电源电压Vdd,根据制造技术节点,其范围可以在0.8V至3V以上。 逻辑零表示地,因此值为0V。
X或x表示当时该值完全未知,可以为0或1。这与布尔逻辑中X的处理方式大不相同,后者表示“无关”。
与任何不完整的电路一样,未连接任何导线的电线在该节点处将具有高阻抗,并由Z或z表示。 即使在Verilog中,任何未连接的导线也会导致高阻抗。
Nets and Variables
Nets and Variables是两个主要的数据类型组,它们代表不同的硬件结构,并且在分配和保留值的方式上也不同。
Nets
Nets用于连接硬件实体(例如逻辑门)之间,因此不会自行存储任何值。 在下图所示的图像中,使用了一个称为net_11的网络来连接与门的输出与触发器的名为data_0的第一输入之间。 以类似的方式,“与”门的两个输入连接到网络net_45和net_67。
有不同类型的网络,每种都有不同的特性,但是在数字设计中最流行和使用最广泛的网络是wire类型。 wire是Verilog数据类型,用于连接元素和连接由单门或连续分配驱动的网络。 该wire类似于用于连接线路板上的两个组件的电线。
如果需要多个 Nets,则可以将它们捆在一起以形成单线(single wire)。 在下面的图像中,我们有一个4位线,可以在每条线上发送4个单独的值。 这种宽度大于1的实体称为向量,我们将在下一篇文章中看到。
wire [3:0] n0; // 4位线(wire)->这是一个向量
重新声明已经由网络,参数或变量声明的名称是非法的,如下代码所示。
module design;
wire abc;
wire a;
wire b;
wire c;
wire abc; // 错误:先前声明了标识符“ abc”
assign abc = a & b | c;
endmodule
Variables(变量)
另一方面,变量是数据存储元素的抽象,可以保存值。 触发器是存储元件的一个很好的例子。
Verilog数据类型reg可用于对硬件寄存器建模,因为它可以保存分配之间的值。 注意,reg不必总是代表触发器,因为它也可以用来代表组合逻辑。
在左图所示的图像中,我们有一个可以存储1位的触发器,而在右边的触发器可以存储4位。
整数(integer)
整数是32位宽的通用变量,可在对硬件进行建模并存储整数值时用于其他目的。
integer Count// Count是一个整数值> 0
time(时间变量)
时间变量是无符号的,64位宽,可用于存储仿真时间量以进行调试。实时变量(real time)只是将时间存储为浮点数。
time end_time; // end_time可以存储类似50ns的时间值
realtime rtime; // rtime = 40.25ps
real
real变量可以存储浮点值,并且可以与整数和reg相同的方式进行分配。
real float; // float = 12.344 - 可以存储浮点数
Example
module testbench;
integer int_a;
real real_b;
time time_c;
initial begin
int_a = 32'hcafe_1234;
real_b = 0.1234567;
#20; // 仿真时间提前20个单位
time_c = $time; // 赋值当前仿真时间
$display ("int_a = 0x%0h", int_a);
$display ("real_b = %0.5f", real_b);
$display ("time_c = %0t", time_c);
end
endmodule
Simulation Log
ncsim> run
int_a = 0xcafe1234
real_b = 0.12346
time_c = 20
ncsim: *W,RNQUIE: Simulation is complete.
Verilog字符串
字符串存储在reg中,并且reg变量的宽度必须足够大以容纳字符串。 字符串中的每个字符代表一个ASCII值,并且每个字符需要1个字节的空间进行存储。 如果变量的大小小于字符串,则Verilog会截断字符串的最左位。 如果变量的大小大于字符串,则Verilog在字符串左侧添加零。
//存储“ Hello World”需要11个字节
reg [8*11:1] str = "Hello World"; // 变量可以存储11个字节,str =“ Hello World”
reg [8*5:1] str = "Hello World"; // 变量仅存储5个字节(其余部分被截断),str =“word”
reg [8*20:1] str = "Hello World"; //变量可以存储20个字节(其余部分用零填充), 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
Simulation Log
ncsim> run
str1 = Hello World
str2 = World
str3 = Hello World
ncsim: *W,RNQUIE: Simulation is complete.
参考文献:
【1】https://www.chipverify.com/verilog/verilog-data-types