数据类型、常量与变量
掌握 Verilog HDL 中 wire、reg、parameter 等核心数据类型
数据类型概览#
Verilog HDL 共有 19 种数据类型,其中 4 个最基本:
| 类型 | 关键词 | 用途 |
|---|---|---|
| 参数型 | parameter | 定义符号常量 |
| 网络型 | wire | 描述组合逻辑连线 |
| 寄存器型 | reg | 描述状态保持单元 |
| 整数型 | integer | 32 位带符号整数变量 |
常量#
整数型常量的三种写法#
| 写法 | 说明 | 示例 |
|---|---|---|
<位宽>'<进制><数字> | 完整格式 | 8'b11000101、8'hC5 |
<进制><数字> | 缺省位宽(至少 32 位) | hC5 |
<数字> | 缺省位宽和进制(十进制) | 197 |
四种进制前缀:
| 进制 | 前缀 | 示例 |
|---|---|---|
| 二进制 | b / B | 8'b1100_0101 |
| 十六进制 | h / H | 8'hC5 |
| 十进制 | d / D | 8'd197 |
| 八进制 | o / O | 8'o305 |
下划线
_可用于增强可读性,如8'b1100_0101,对编译无影响。
x 值与 z 值#
8'b1001xxxx // 低4位为不定值 x
8'h9x // 低4位为不定值 x(十六进制表示)
8'b1010zzzz // 低4位为高阻值 z
8'haz // 低4位为高阻值 zverilog负数#
-8'd5 // 合法:在位宽前加负号
8'd-5 // 非法:负号不能放在位宽与进制之间verilogparameter 符号常量#
parameter addrwidth = 16; // 合法
parameter msb = addrwidth - 1; // 合法:引用已定义的符号常量
parameter addrwidth = datawidth * 2; // 非法:datawidth 未在此前定义verilog变量#
(1) 网络型(nets)变量#
输出始终随输入变化的变量,需要被持续驱动。
| 类型 | 说明 |
|---|---|
wire、tri | 普通连线(功能相同) |
wor、trior | 具有线或特性的连线 |
wand、triand | 具有线与特性的连线 |
tri1、tri0 | 上拉 / 下拉电阻 |
supply1、supply0 | 电源(逻辑 1)/ 地(逻辑 0) |
wire 型声明格式:
wire a, b, c; // 单位宽连线
wire [7:0] data_bus; // 8 位总线
wire [n-1:0] d1, d2, d3; // n 位,共 3 个变量verilog- 模块输入 / 输出端口的缺省类型为
wire - 常用于
assign语句赋值的组合逻辑信号
(2) 寄存器型(register)变量#
对应具有状态保持作用的电路元件(触发器、寄存器等)。
| 类型 | 说明 |
|---|---|
reg | 常代表触发器,也可是组合逻辑 |
integer | 32 位带符号整数 |
real | 64 位带符号实数 |
time | 无符号时间变量 |
reg 型声明格式:
reg q; // 1 位寄存器
reg [7:0] out; // 8 位寄存器
reg [4:1] regc, regd; // 4 位寄存器,共 2 个verilogwire 与 reg 的根本区别:
| 对比项 | wire | reg |
|---|---|---|
| 赋值方式 | assign 语句(连续赋值) | 过程赋值语句(always、initial 等) |
| 保持值 | 不保持,随驱动变化 | 在重新赋值前一直保持原值 |
| 生成电路 | 只能生成组合逻辑 | 可生成触发器或组合逻辑 |
reg 生成组合逻辑 vs 触发器#
Verilog HDL
1 // reg 生成组合逻辑(电平触发)
2 module rw1 (a, b, out1, out2);
3 input a, b;
4 output out1, out2;
5 reg out1;
6 wire out2;
7 assign out2 = a; // wire:连续赋值 wire 赋值
8 always @(b) 电平触发
9 out1 <= ~b; // reg:电平触发 → 组合逻辑 组合逻辑
10 endmodule
wire 赋值 assign 只能驱动 wire 型变量
电平触发 敏感信号为电平,b 变化时执行
组合逻辑 虽用 reg,但实际生成组合逻辑而非触发器
Verilog HDL
1 // reg 生成触发器(边沿触发)
2 module rw2 (clk, d, out1, out2);
3 input clk, d;
4 output out1, out2;
5 reg out1;
6 wire out2;
7 assign out2 = d & ~out1; // wire:组合逻辑
8 always @(posedge clk) 边沿触发
9 out1 <= d; // reg:边沿触发 → 触发器 触发器
10 endmodule
边沿触发 posedge clk:时钟上升沿触发
触发器 边沿触发的 reg 赋值综合成触发器
(3) 数组型(memory)变量#
由若干个相同宽度的 reg 向量构成的数组,用于对存储器建模。
reg [n-1:0] 存储器名 [m-1:0]; // m 个存储单元,每个 n 位宽verilogreg [7:0] mem [255:0]; // 256 个字节的存储器(ROM/RAM 建模)
reg [n-1:0] rega; // 一个 n 位的寄存器(非数组)
reg mema [n-1:0]; // n 个 1 位寄存器组成的存储器verilog注意:
reg[n-1:0] rega是单个 n 位寄存器;reg mema[n-1:0]是 n 个 1 位存储单元的数组,两者含义不同。
信号类型确定方法总结#
信号
├── 端口信号(出现在端口列表中)
│ ├── 输入端口 → 只能是 net 类型(wire)
│ └── 输出端口
│ ├── 在过程块中赋值 → register 类型(reg)
│ └── 在过程块外赋值(assign/例化)→ net 类型(wire)
└── 内部信号
├── 在过程块中赋值 → register 类型(reg)
└── 在过程块外赋值 → net 类型(wire)plaintext