注释
- 单行注释:使用
//
,注释内容从//
开始到该行结束。 - 多行注释:使用
/* ... */
,注释内容被包含在/*
和*/
之间。
关键字
常用的关键字:
module
:定义模块的关键字。input
:定义输入端口。output
:定义输出端口。wire
:定义连线类型。reg
:定义寄存器类型。assign
:连续赋值语句。always
:描述时序逻辑。initial
:描述初始化行为。begin
和end
:用来界定代码块。
更多的关键字:
模块定义与端口声明
- module:用于定义一个模块,是Verilog程序的基本单元。
- endmodule:用于结束一个模块的定义。
- input:声明输入端口,用于接收来自外部模块或其他实例的数据。
- output:声明输出端口,用于将模块内部的数据发送给外部模块或其他实例。
- inout:声明双向端口,既可以用作输入端口,也可以用作输出端口,通常用于需要双向通信的场合。
数据类型声明
- wire:用于声明线网类型的变量,通常用于组合逻辑。线网型变量用于模拟硬件中的连线,表示组合逻辑中的连线或信号。
- reg:用于声明寄存器类型的变量,通常用于时序逻辑。寄存器变量用于存储状态信息,表示时序逻辑中的寄存器。
- integer:用于声明整数类型的变量,可以进行算术运算。
- parameter:用于声明参数,通常用于定义常量值。这些常量在整个模块中都是可见的,并且可以在模块实例化时通过实例化语句传递不同的值。
- localparam:用于声明局部常量,这些常量仅在定义它的模块内部可见。
控制流语句
- if:条件语句,用于根据条件执行不同的操作。
- else:与if配合使用,表示条件为假时的执行路径。
- case:多路选择语句,根据不同的条件执行不同的操作。case语句中所有表达式值的位宽必须相等。
- for:循环语句,用于重复执行某些操作。
- while:另一种循环语句,与for类似,但通常用于更灵活的循环控制。
块语句
- begin 和 end:用于组合多个语句,形成一个语句块。在语句块中,可以包含多个控制流语句和赋值语句。
- initial:初始化块,用于在仿真开始时执行代码。initial块只无条件执行一次。
- always:总是块,用于创建时序逻辑或组合逻辑。always块在满足条件时不断执行,可以描述电平触发或边沿触发的逻辑。
赋值语句
- =:阻塞赋值,在同一个always过程中,后面的赋值语句要等待前一个赋值语句执行完。
- <=:非阻塞赋值,在同一个always过程中,非阻塞赋值语句是同时进行的,排在后面的语句不会被该赋值语句阻塞。非阻塞赋值通常用于描述可综合的时序电路。
- assign:持续赋值语句,用于给信号或寄存器赋值,包括简单的逻辑运算和条件语句等。被赋值的信号通常是wire类型。
时序控制
- #:延迟操作符,用于指定延迟时间。
- @(posedge clk):时钟上升沿敏感的事件控制,表示在时钟上升沿时触发执行的操作。
- @(negedge clk):时钟下降沿敏感的事件控制,表示在时钟下降沿时触发执行的操作。
其他关键字
- task:用于定义任务,可以包含一系列的语句。任务可以定义自己的仿真时间单位,但不能返回值。
- endtask:用于结束任务的定义。
- function:用于定义函数,必须返回一个值。函数与主模块共用同一个仿真时间单位,至少要有一个输入变量。
- endfunction:用于结束函数的定义。
- `define:宏定义,用于定义宏。
- `include:包含指令,用于包含其他文件的内容。
验证与调试
- display∗∗和∗∗monitor:用于调试Verilog模块,输出调试信息和信号值。
程序框架
// 这是一个简单的 Verilog 程序框架示例
module simple_example (
input wire clk, // 时钟输入
input wire reset, // 重置输入
output reg out_signal // 输出信号
);
// 初始化输出信号为0
initial begin
out_signal = 0;
end
// 时序逻辑:在每个时钟上升沿执行
always @(posedge clk) begin
if (reset) begin
// 如果重置信号为高,则将输出信号置为0
out_signal <= 0;
end else begin
// 否则,将输出信号取反
out_signal <= ~out_signal;
end
end
endmodule
说明:
1.定义了一个名为 simple_example
的模块,包含三个端口:时钟 clk
、重置 reset
(输入),和输出信号 out_signal
2.使用 initial
块来初始化 out_signal
为0。这个块在仿真开始时执行一次。
3.使用 always
块和 posedge
(正边沿)来定义在每个时钟上升沿执行的行为。如果 reset
信号为高,则将 out_signal
置为0;否则,将 out_signal
取反。