目录
Verilog 基础语法概述
Verilog 是一种硬件描述语言 (HDL),用于描述数字电路的结构和行为。它被广泛应用于 FPGA、ASIC 的设计与验证。Verilog 语言本身的语法结构与 C 语言类似,但专门为硬件设计进行了优化。其基本语法包括模块定义、数据类型、运算符、控制结构、时序控制等。
模块定义
在 Verilog 中,设计是由模块 (module) 组成的。每个模块通过 module
关键字定义,模块的端口(输入和输出)通过端口列表定义。
module module_name(input_port, output_port);
// 输入端口定义
input wire [3:0] input_port;
// 输出端口定义
output wire [3:0] output_port;
// 模块内容
endmodule
端口类型
- input:表示输入端口。
- output:表示输出端口。
- inout:表示双向端口,既可输入也可输出。
端口的定义方式
端口可以是单比特或多比特(位宽定义)。例如,input [3:0]
表示一个 4 位宽的输入端口。
数据类型
Verilog 中的基本数据类型包括:
- wire:表示电路的连接线或信号线。通常用于组合逻辑。
- reg:表示寄存器,通常用于存储信号的状态。在时序逻辑中使用。
- integer:整数类型,通常用于描述数值。
- real:实数类型,通常用于模拟电路的计算。
- time:表示时间单位,通常用于仿真。
示例:定义数据类型
module example;
wire [3:0] signal; // 4 位宽的信号线
reg [7:0] register; // 8 位宽的寄存器
integer count; // 整数类型
real delay_time; // 实数类型
time clk_time; // 时间类型
endmodule
运算符
Verilog 支持与 C 语言类似的各种运算符。常见的运算符包括:
1. 算术运算符
+
:加法-
:减法*
:乘法/
:除法%
:取余
2. 比较运算符
==
:相等!=
:不等<
:小于>
:大于<=
:小于等于>=
:大于等于
3. 逻辑运算符
&&
:逻辑与||
:逻辑或!
:逻辑非
4. 位运算符
&
:按位与|
:按位或^
:按位异或~
:按位非<<
:左移>>
:右移
5. 条件运算符
assign result = (a > b) ? 1 : 0; // 如果 a > b,result 为 1,否则为 0
常见控制结构
Verilog 提供了多种控制结构,用于描述电路的行为。
1. if-else 语句
always @ (a or b) begin
if (a > b)
y = a;
else
y = b;
end
2. case 语句
Verilog 中的 case
语句可以用来选择多个条件中的一个。它类似于 C 语言中的 switch
语句。
always @ (select) begin
case(select)
2'b00: y = 4'b0001;
2'b01: y = 4'b0010;
2'b10: y = 4'b0100;
2'b11: y = 4'b1000;
default: y = 4'b0000;
endcase
end
3. 循环语句
Verilog 支持 for
、while
和 repeat
循环语句。
for
循环
for (i = 0; i < 10; i = i + 1) begin
// 执行循环体
end
while
循环
while (a < 10) begin
a = a + 1;
end
repeat
循环
repeat (5) begin
// 执行循环体
end
时序控制
Verilog 主要用于描述硬件的时序行为,时序控制主要依赖于时钟信号和复位信号。常见的时序控制语句包括 always
和 initial
。
1. always 块
always
块用来描述时序逻辑,它是由时钟信号驱动的,通常用于描述触发器和状态机。
always @ (posedge clk or negedge rst) begin
if (~rst)
q <= 0;
else
q <= d;
end
- posedge:上升沿触发
- negedge:下降沿触发
2. initial 块
initial
块在仿真开始时执行一次。通常用于初始化信号或设置初始条件。
initial begin
a = 0;
b = 1;
end
3. 延迟与事件控制
Verilog 支持对信号的延迟控制和事件控制。
#10 a = 1; // 延迟 10 个时间单位后将 a 赋值为 1
Verilog 实例
以下是一个简单的 Verilog 示例,展示了如何用 Verilog 语言设计一个 4 位加法器:
module adder (
input [3:0] a, b, // 输入信号
output [3:0] sum, // 输出信号
output carry_out // 进位输出
);
assign {carry_out, sum} = a + b; // 通过加法器计算和与进位
endmodule
Testbench 示例
为了验证加法器的正确性,可以编写一个简单的 Testbench:
module testbench;
reg [3:0] a, b; // 输入信号
wire [3:0] sum; // 输出信号
wire carry_out; // 进位输出
adder uut (
.a(a),
.b(b),
.sum(sum),
.carry_out(carry_out)
);
initial begin
a = 4'b0101; b = 4'b0011; // 设置输入值
#10;
a = 4'b1111; b = 4'b0001; // 修改输入值
#10;
$finish; // 结束仿真
end
initial begin
$monitor("a=%b, b=%b, sum=%b, carry_out=%b", a, b, sum, carry_out);
end
endmodule
发表回复