1、程序结构
- Verilog程序是由模块构成的。每个模块的内容都嵌在module和endmodule两个关键字之间;
- 每个模块实现特定的功能;模块是可以进行层次嵌套的。
- 每个模块首先要进行端口定义,并说明输入和输出(input、output或inout),然后对模块的功能进行逻辑描述。
- Verilog程序书写格式自由,一行可以写几个语句,一个语句也可以分多行写。除end等少数语句外,每个语句的最后必须有分号。
- 可以用 /*……*/ 和 //…… 作注释。好的源程序都应当加上必要的注释,以增强程序的可读性和可维护性。
基本框架:
module mux2( //module是模块关键词标识 后接模块名 2选1多路器
//()内写模块的端口列表
a,
b,
sel,
out
);//括号后面要加分号
input a;//对端口进行说明,input为输入,output为输出
input b;
input sel;
output out;
assign out =(sel==1)?a:b;//assign关键词,之后接连续赋值语句 %被赋值的值 = 赋值
//三元运算符 当sel=1时,a赋值给out,否则b赋值给out
endmodule //endmodule是模块关键词标识
Verilog模块的模板
module 顶层模块名(输入输出端口列表);
output 输出端口列表; //输出端口声明
input 输入端口列表; //输入端口声明
reg 信号名;/*定义数据,信号的类型,函数声明*/
//逻辑功能定义
assign 结果信号名=表达式; //使用assign语句定义逻辑功能
always @ (敏感信号表达式) //用always块描述逻辑功能
begin
//过程赋值语句;if-else,case语句;for循环语句;task,function调用
end
调用模块名 例化模块名(端口列表port_list); //调用其他模块
门元件关键字 例化门元件名(端口列表port_list); //门元件例化
endmodule
编好代码后,运行Run Synthesis进行分析综合。综合无误后进行仿真分析。创建仿真文件,仿真文件名与源文件名一致,后面跟个_tb。以下为仿真文件的编写。
`timescale 1ns/1ns //关键词timescale 时间步进/时间精度
//#1;//延时1ns 测试文件其实就是设计一个平台,对你所设计的模块进行例化,给予信号激励,观测输出结果
module mux2_tb();//测试文件没有端口,只是用来仿真
//定义激励信号
//设计中所有的信号类型定义,只有reg型和wire型。其中,激励信号用reg型定义,可寄存信号,而wire型
//用于连接端口到端口,无寄存功能,可直接输出
reg s_a;
reg s_b;
reg sel;
wire out;
//模块的例化
mux2 mux2( //模块名 例化名称( 例化名称可以和模块名一致
.a(s_a),// .a(信号名) 这个仿真名可以与原信号一致
.b(s_b),
.sel(sel),
.out(out)
);
initial begin //initial块
s_a=0;s_b=0;sel=0;
#200;//延迟200ns
s_a=0;s_b=0;sel=1;
#200;
s_a=0;s_b=1;sel=0;
#200;
s_a=0;s_b=1;sel=1;
#200;
s_a=1;s_b=0;sel=0;
#200;
s_a=1;s_b=0;sel=1;
#200;
s_a=1;s_b=1;sel=0;
#200;
s_a=1;s_b=1;sel=1;
#200;
$stop;//停止
end
endmodule
注意事项
1、`timescale 1ns/1ns //关键词timescale 时间步进/时间精度 这里的`是左上角的。
2、reg型和wire型的区别。
wire
类型表示一种连续赋值的连接,用于驱动连接点之间的信号。wire
类型的信号不能存储值,只能传递值,适用于组合逻辑。