Verilog 数据类型
Verilog 语言中数据类型的主要目的是表示数据存储元素(如触发器中的位)和传输元素(如连接逻辑门和顺序结构的导线)。
变量持有什么值?
除了 real
之外,几乎所有的数据类型都只能具有下面给出的四种不同值之一 和 event
数据类型。
0 | 表示逻辑零或错误条件 |
1 | 代表逻辑一,或真条件 |
x | 表示一个未知的逻辑值(可以是零或一) |
z | 代表高阻态 |
下图显示了这些值如何在时序图和仿真波形中表示。大多数模拟器使用这种约定,其中 red 代表X
和橙色 中间代表高阻抗或Z
.
verilog 值集意味着什么?
由于 Verilog 本质上用于描述触发器等硬件元素和 NAND 和 NOR 等组合逻辑,因此它必须对硬件中的价值系统进行建模。逻辑 1 表示电源电压 Vdd 根据制造技术节点,其范围可以在 0.8V 到超过 3V 之间。逻辑零表示 ground 因此值为 0V。
X
或 x
表示该值当时只是未知的,可以是 0 或 1。这与 X
的方式完全不同 以布尔逻辑处理,意思是“不关心”。
与任何不完整的电路一样,未连接任何东西的导线在该节点处将具有高阻抗,并由 Z
表示 或 z
.即使在verilog中,任何未连接的线都会导致高阻抗。
网络和变量
网 和变量 是两组主要的数据类型,它们代表不同的硬件结构,并且在分配和保留值的方式上有所不同。
篮网
网 用于连接逻辑门等硬件实体之间,因此不单独存储任何值。在下图中,名为 net_11 的网络用于连接 AND 门的输出和触发器的第一个输入,称为 data_0。以类似的方式,与门的两个输入连接到网络 net_45 和 net_67。
<无脚本>
有不同类型的网络,每一种都有不同的特点,但最流行和使用最广泛的 net 在数字设计中是类型 wire
.一个 wire
是一种 Verilog 数据类型,用于连接元素和连接由单个门或连续分配驱动的网络。 wire
类似于用于连接面包板上两个组件的电线。
当需要多个网络时,可以将它们捆绑在一起形成单个wire
.在下图中,我们有一根 4 位线,可以在每根线上发送 4 个单独的值。这种宽度大于 1 的实体称为向量,我们将在下一篇文章中看到。
wire [3:0] n0; // 4-bit wire -> this is a vector
<无脚本> 如下代码所示,重新声明已经由网络、参数或变量声明的名称是非法的。
module design;
wire abc;
wire a;
wire b;
wire c;
wire abc; // Error: Identifier "abc" previously declared
assign abc = a & b | c;
endmodule
变量
<无脚本>另一方面,变量是数据存储元素的抽象,可以保存值。触发器是存储元件的一个很好的例子。
Verilog 数据类型 reg
可用于对硬件寄存器进行建模,因为它可以在分配之间保存值。请注意,reg
不必总是表示触发器,因为它也可以用来表示组合逻辑。
在左图中,我们有一个可以存储 1 位的触发器,而右侧的触发器可以存储 4 位。
<无脚本>其他数据类型
整数
一个 integer
是一个 32 位宽的通用变量,在对硬件进行建模和存储整数值时可用于其他目的。
integer count; // Count is an integer value > 0
时间
一个 time
变量是无符号的,64 位宽,可用于存储仿真时间量以进行调试。 realtime
变量只是将时间存储为浮点数。
time end_time; // end_time can be stored a time value like 50ns
realtime rtime; // rtime = 40.25ps
真实
一个 real
变量可以存储浮点值,可以像integer
一样赋值 和 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.
Verilog 字符串
字符串存储在 reg
,以及 reg
的宽度 变量必须足够大以容纳字符串。字符串中的每个字符代表一个 ASCII 值,需要 1 个字节。如果变量的大小小于字符串,则 Verilog 会截断字符串的最左侧位。如果变量的大小大于字符串,则 Verilog 会在字符串的左侧添加零。
// "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
请注意,str1 具有正确的大小来存储字符串“Hello World”的所有 11 个字节,因此整个字符串都会被打印出来。然而 str2 只能存储 5 个字节,因此前 6 个字节被截断并最终只存储“世界”。第三个变量 str3 大于 11 个字节,并在左侧填充空格,因此其中存储的值变为“Hello World”。
模拟日志ncsim> run str1 = Hello World str2 = World str3 = Hello World ncsim: *W,RNQUIE: Simulation is complete.
Verilog