Verilog HDL语言学习1
在modelsim中仿真的时候已经发现了两个文件,分别是name.v和name_tb.v.
name.v 是设计文件,主要功能是包含实际的硬件描述,也就是模块,通常包含设计的模块、端口、信号、内部逻辑等
name_tb.v 是测试文件,主要用于测试你的模块是否按照预期的功能执行的。
有点像是C语言的.h文件声明函数,然后再其他的.C 文件里调用的意思。可能这会儿还不是很确定,但是一旦接触到name.v文件里模块的声明,就会发现很贴合了。
先说说VerilogHDL语言大体结构
先给name.v文件写点代码如下
module compare(equal,a,b);
input a,b;
output equal;
assign equal=(a==b)?1:0; //a 等于 b 时,equal 输出为 1;a 不等于 b 时,
//equal 输出为 0。
endmodule
再给name_tb.v文件写代码如下:
`timescale 1ns/1ns //定义时间单位。
module comparetest;
reg a,b;
wire equal;
initial //initial 常用于仿真时信号的给出。
begin
a=0;
b=0;
#100 a=0; b=1;
#100 a=1; b=1;
#100 a=1; b=0;
#100 $stop; //系统任务,暂停仿真以便观察仿真波形。
end
compare compare1(.equal(equal),.a(a),.b(b)); //调用模块。
endmodule
仿真的波形如下
①首先发现无论是name或者name_tb文件里的代码,都是在module和endmodule这两个关键字里面的(暂时称为关键字),所以就像函数体的声明和编写一样。
②再然后发现在name里面函数体的内容和name_tb函数体里面的内容,很明显在name_tb的函数体对name里面的函数体进行了调用的关系。
③观察下面name里面的这一句代码
assign equal=(a==b)?1:0; //a 等于 b 时,equal 输出为 1;a 不等于 b 时,
有一个很明显的语句就是三目运算符,从意思很好理解,就是相同返回1的功能,就是异或功能。
再看看name_tb里的调用
begin
a=0;
b=0;
#100 a=0; b=1;
#100 a=1; b=1;
#100 a=1; b=0;
#100 $stop; //系统任务,暂停仿真以便观察仿真波形。
end
compare compare1(.equal(equal),.a(a),.b(b)); //调用模块。
compare compare1(.equal(equal),.a(a),.b(b));这一句实现了模块的调用,而前面则是对a和b参数的设置,“#100”的作用可以从波形上看出有点像是延时的意思。
④看波形不难看出,当a和b相同的时候,输出equal变成了1,当不相同的时候变成了0。
那么大概总结一下在.v文件里的代码该怎么去编写
首先创造模块 具体语法是
module 模块名(变量1,变量2.....);
然后编写模块内容,内容主要包含IO口的说明,内部信号的说明和功能的编写。
1.输入 input 输入1,输入2,输入3,输入4;
2.输出 output 输出1,输出2,输出3,输出4;
可以在module声明的时候就声明,如下
module LED(input 输入1,output 输出1);
//同时也能指定输入输出的位长度
然后就是内部信号的说明,具体格式如下;
reg [width-1 : 0] R变量1,R变量2 。。。。;
wire [width-1 : 0] W变量1,W变量2 。。。。;
//width按理来说可以任意设置
有了变量就可以编写功能了,功能的编写格式如下
//① 用assign 关键字编写,格式如下
assign a=b&c;
//② 用always块
always @(posedge clk or posedge clr)
begin
if(clr) q <= 0;
else if(en) q <= d;
end
//采用“assign”语句是描述组合逻辑最常用的方法之一。而“always”块既可用于描述组合逻辑也可描述时序逻辑
结束