Verilog 语法详解:核心定位与基础实战
一、Verilog 核心定位与语法框架
-
核心特点
- 并行性:模块内的所有语句(如
assign、always块)同时执行,对应硬件的并行工作,而非像软件那样按代码顺序串行执行。 - 硬件映射:每段语法都对应明确的硬件结构。比如
reg对应寄存器,wire对应导线,逻辑运算符对应逻辑门。 - 层次化:通过'模块定义 + 例化'实现复杂设计,这是构建大型数字系统的基础。
- 并行性:模块内的所有语句(如
-
基本语法框架 Verilog 程序由模块(Module)组成,模块是最小的可综合单元。一个完整的 Verilog 代码结构通常包含宏定义、端口声明、内部信号和逻辑描述。
// 1. 宏定义(可选,全局生效)
`define WIDTH 8 // 大写命名,编译时替换
// 2. 模块定义(必须,可综合代码的核心)
module demo(
// 端口列表:输入/输出/双向
input [WIDTH-1:0] i_data, // 输入端口(8 位)
input i_clk, // 时钟输入(1 位)
input i_rst_n, // 同步复位(低有效)
output reg [WIDTH-1:0] o_data // 输出端口(寄存器型,8 位)
);
// 3. 内部信号定义(wire/reg/parameter 等)
wire [WIDTH-1:0] w_temp; // 线网型信号(导线)
reg [3:0] r_cnt; // 寄存器型信号(计数器)
// 4. 逻辑描述(组合逻辑/时序逻辑)
// 组合逻辑:assign 连续赋值(对应 wire)
assign w_temp = i_data + 1'b1;
// 时序逻辑:always 块(时钟触发,对应寄存器)
always @(posedge i_clk) begin
if (!i_rst_n) begin // 复位逻辑(优先级最高)
o_data <= 8'd0;
r_cnt <= 4'd0;
end else begin
o_data <= w_temp; // 寄存器赋值(<= 非阻塞赋值)
r_cnt <= r_cnt + 1'b1;
end
end
endmodule // 模块结束(必须与 module 成对)
Verilog 是硬件描述语言(HDL)的核心标准之一,用于描述数字电路的结构和行为,最终映射为实际硬件(如 FPGA、ASIC)。与 C/C++ 等软件语言的'串行执行'不同,Verilog 的核心是'并行硬件映射'——代码的每一部分都对应具体的电路元件。
二、基础语法:模块与端口
- 模块定义(Module Definition) 模块是 Verilog 的基本单元,语法格式如下:
module 模块名 (
端口 1,
端口 2,
...
端口 N
); // 端口声明 + 内部信号 + 逻辑描述
endmodule
* **模块名**:大小写敏感,建议与文件名一致(如 `top.v` 对应模块 `top`)。
* **端口列表**:必须在模块开头声明,或在模块内显式声明(推荐前者,可读性强)。
2. 端口类型与声明 端口按方向分为三类,需明确声明类型(input/output/inout)和位宽(默认 1 位):
| 端口类型 | 功能描述 | 硬件映射 | 允许连接的信号 |
|---|---|---|---|
| input | 模块输入(外部→模块) | 导线(wire) | 父模块的 wire/reg/常量 |
| output | 模块输出(模块→外部) | 导线(wire) | 父模块的 wire(不可常量) |
| inout | 双向端口(模块↔外部) | 导线(wire) | 父模块的 wire(需三态) |
端口声明示例:
// 方式 1:端口列表 + 内部声明(推荐)
module demo(
input clk, // 1 位输入(时钟)
input [7:0] din, // 8 位输入(数据)
output [7:0] dout, // 8 位输出(导线型)
output reg [3:0] cnt, // 4 位输出(寄存器型)
inout io_data // 双向端口
);
// 方式 2:仅端口列表,内部声明(兼容旧语法)
module demo(clk, din, dout, cnt, io_data);
input clk;
input [7:0] din;
output [7:0] dout;
output reg [3:0] cnt;
inout io_data;
endmodule
关键注意:
output端口默认是wire型,若需要在always块中赋值(时序逻辑),需显式声明为output reg。inout端口必须是wire型,需通过三态门控制方向,例如assign io_data = en ? data : 1'bz。
三、核心数据类型
Verilog 数据类型分为线网型(Net)和寄存器型(Register),核心区别在于'是否存储数据',这直接对应硬件中的'导线'和'寄存器'。
-
线网型(Net):无存储,实时响应输入 线网型对应硬件中的'导线',必须通过
assign连续赋值或模块输出驱动,无默认值(默认高阻 z)。常用线网类型:
类型 功能描述 应用场景 wire 最常用,单驱动源 组合逻辑输出、模块端口连接 tri 多驱动源(三态) 双向总线(如地址总线) tri0 下拉电阻(默认 0) 复位信号(默认低) tri1 上拉电阻(默认 1) 使能信号(默认高) 示例:
wire [7:0] data_w; // 8 位线网信号
tri bus; // 三态总线
assign data_w = a + b; // 连续赋值(wire 必须用 assign)
assign bus = en ? data : 1'bz; // 三态控制(en=1 时输出 data,否则高阻)
- 寄存器型(Register):有存储,时钟触发更新
寄存器型对应硬件中的'寄存器'或'触发器',需在
always块中赋值,且通常对应触发器或锁存器。这类变量在仿真中会保持状态,直到被新值覆盖。


