本系列文章基于罗杰老师的verilog HDL入门与FPGA系统设计
介绍一些典型的模块verilog语言编写。
VerilogHDL模块举例
案例1:
图2.2.2是2选1数据选择器电路。该电路的逻辑表达式为:Y=(~S)*D0+S *D1
现在用 VerilogHDL三种不同的描述方式写代码:
1.结构风格或者门级的描述方式
核心是使用预先定义好的逻辑门元件来描述,故称之为门级模型。代码名为Mux2to1_structural.v.代码如下:
//文件名:Mux2to1_structural.v
module Mux2to1_structural(
input D0,D1,S,//输入输出端口声明
output Y);
wire Snot,A,B;//内部节点声明
not U1(Snot,S);
and U2(A,D0,Snot);
and U3(B,D1,S);
or U4(Y,A,B);
endmodule
调用基本的门级元件时,可以省略调用名。输出端口总是在左边第一个位置。
2.数据流描述方式
//文件名:Mux2to1_structural.v
module Mux2to1_structural(
input D0,D1,S,//输入输出端口声明
output wire Y);//电路功能描述Y必须是WIRE型。
assign Y = (~S & D0)|(S & D1);//|是指取并集,此句子也可以写成:assign Y = S?D1:D0 //意思是当s等于1时取d1,当s等于0时取d0
endmodule
3.行为风格的描述方式:
对于功能复杂的电路,用门级描述或者数据流描述电路的方式效率较低。可以利用更为抽象的行为风格描述方式直接写代码。使用begin end语句块,称为有名块。是一种对于复杂数据块进行描述时高效的代码描述风格
//版本1:文件名:Mux2to1_structural.v
module Mux2to1_structural(
input D0,D1,S,//输入输出端口声明
output reg Y);
always@(S or D0 or D1)
begin:
if(S==1)
Y = D1;
else Y = D0;
end
endmodule
//版本2:文件名:Mux2to1_structural.v
module Mux2to1_structural(
input D0,D1,S,//输入输出端口声明
output reg Y);
always@(S or D0 or D1)
begin:
case(S)
1'b0:Y = D1;
1'b1:Y = D0;
endcase
endmodule
强调:行为描述语句always语句,是一条典型的循环语句,它后面的是执行循环体的条件,表示在任意一个输入信号发生变化是,后面的过程赋值语句都会被执行一次。执行完最后一条语句时暂停,等待always信号再次变化。
注意:always begin: end结构体,写always不加冒号,begin加冒号,写begin一定要写end。
没有always而直接使用if-else和case-endcase就会出现错误。而且要注意:always内部被复制的信号都要是reg类型才可以。不然就会报错。
编写测试模块
代码写好后要进行编译,看看波形,这时就需要编写测试模块。声明信号时,激励信号数据要求是reg类型,输出信号要求是wire类型。
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/04/09 14:12:35
// Design Name:
// Module Name: test_Mux2to1
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module test_Mux2to1(
);
reg PD0,PD1,PS;
wire PY;
Mux2to1_structural
mux1(.D0(PD0),
.D1(PD1),
.S(PS),
.Y(PY));
initial begin
PS = 0;PD1 = 0;PD0 = 0;
#1 PS = 0;PD1 = 0;PD0 = 1;
#1 PS = 0;PD1 = 1;PD0 = 0;
#1 PS = 0;PD1 = 1;PD0 = 1;
#1 PS = 1;PD1 = 0;PD0 = 0;
#1 PS = 1;PD1 = 0;PD0 = 1;
#1 PS = 1;PD1 = 1;PD0 = 0;
#1 PS = 1;PD1 = 1;PD0 = 1;
#1 PS = 0;PD1 = 0;PD0 = 0;
#1 $stop;
end
endmodule
这段代码的作用是:输入激励PS\PD1\PD0得出输出PY,利用Mux2to1_structural函数,将对应变量进行链接,最后得出PY,此时我们可以进行仿真波形了。
仿真波形展示: