Verilog 数据类型详解:位、线网与逻辑值
Verilog 数据类型的主要目的是表示数据存储元件(如触发器中的位)和传输元件(如连接逻辑门和时序结构的线网)。
变量可取值
除 real 和 event 外,几乎所有数据类型仅可取以下四种值:
| 0 | 逻辑 0,或假条件 |
| 1 | 逻辑 1,或真条件 |
| x | 未知逻辑值(可能是 0 或 1) |
| z | 高阻抗状态 |
下图展示这些值在时序图和仿真波形中的表示。大多数仿真器约定:红色 代表 X,中间 橙色 代表高阻抗 Z。
Verilog 值集的含义
Verilog 用于描述触发器、与非门、或非门等硬件元件,必须建模硬件中的值系统。逻辑 1 代表电源电压 Vdd,范围 0.8V 至 3V 以上,取决于工艺节点。逻辑 0 代表 地,即 0V。
X 或 x 表示值未知,可能是 0 或 1。这与布尔逻辑中“don't care”的 X 含义截然不同。
如同任何未完成电路,未连接的线网在该节点呈高阻抗,用 Z 或 z 表示。Verilog 中任何未连接线网也将导致高阻抗。
线网与变量
线网 和 变量 是两大数据类型组,分别代表不同硬件结构,赋值和保持值的方式不同。
线网
线网 用于连接逻辑门等硬件实体,自身不存储值。下图中,线网 net_11 连接与门输出与触发器 data_0 的第一个输入。与门的两个输入分别连接 net_45 和 net_67。
线网有多种类型,各有特性,但数字设计中最常用的是 wire 类型。wire 用于连接元件,连接由单个门或连续赋值驱动的线网。类似面包板上连接两个元件的电线。
需要多条线网时,可将它们捆绑成单个 wire。下图展示 4 位 wire 可在每根线上传输独立值。宽度大于 1 的实体称为向量,下文详述。
wire [3:0] n0; // 4-bit wire -> 这是一个向量
重复声明已由线网、参数或变量声明的名称是非法的:
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
integer 是 32 位通用变量,用于建模硬件时的其他目的,存储整数值。
integer count; // Count 是大于 0 的整数值
time
time 变量为无符号 64 位,用于存储仿真时间量以便调试。realtime 变量以浮点数存储时间。
time end_time; // 可存储如 50ns 的时间值
realtime rtime; // rtime = 40.25ps
real
real 变量存储浮点值,赋值方式同 integer 和 reg。
real float; // float = 12.344 - 可存储浮点数
示例
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 系统任务打印所有变量
$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 截断字符串左侧位;若变量尺寸大于字符串,左侧补零。
// "Hello World" 需 11 字节
reg [8*11:1] str = "Hello World"; // 变量可存 11 字节,str = "Hello World"
reg [8*5:1] str = "Hello World"; // 变量仅存 5 字节(其余截断),str = "World"
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
注意:str1 尺寸刚好存下 "Hello World" 全部 11 字节,完整打印。str2 仅能存 5 字节,高 6 字节被截断,只存 "World"。str3 大于 11 字节,左侧填充空格,存储值为 " Hello World"。
仿真日志
ncsim> run str1 = Hello World str2 = World str3 = Hello World ncsim: *W,RNQUIE: Simulation is complete.
Verilog
- 五大数据中心模型详解:设计架构、适用场景与典型案例
- 2021年云计算八大核心模型全解析:服务模式与部署模式
- 8大常见数据泄露类型实战剖析:真实案例、影响深度与防御启示
- 精通C#变量与基础数据类型:完整指南
- 深入理解 C++ 数据类型:基础类型、修饰符与最佳实践
- C 语言数据类型详解:int、float、char 等核心类型完全指南
- C 语言数据类型完全指南:整型、浮点型、void 与派生类型
- Verilog 入门:数字电路设计完整教程
- 掌握 Verilog 拼接操作:实用指南
- MATLAB 数据类型完全指南:15 种基本类型、转换函数与类型判断函数速查表
- 精通Python数据类型:实战指南
- Java 基本数据类型:8 大类型完整指南与示例