微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Verilog HDL基础之:程序基本结构

Verilog HDL基础之:程序基本结构

时间:06-05 来源:互联网 点击:

口声明

output out; //端口说明

input in, enable;

mytri tri_inst(out,in,enable);//实例化由mytri模块定义的实例元件tri_inst

endmodule

module mytri(out,in,enable); //三态启动器模块端口声明

output out; //端口说明

input in, enable;

assign out = enable? in : bz; //三态启动器算法描述

endmodule

这个例子通过另一种方法描述了一个三态门。在这个例子中存在着两个模块。模块trist1调用由模块mytri定义的实例元件tri_inst。模块trist1是顶层模块。模块mytri则被称为子模块。

通过上面的例子可以看到。

  • Verilog HDL程序是由模块构成的。每个模块的内容都是嵌在module和endmodule两个语句之间。每个模块实现特定的功能。模块是可以进行层次嵌套的。正因为如此,才可以将大型的数字电路设计分割成不同的小模块来实现特定的功能,最后通过顶层模块调用子模块来实现整体功能。
  • 每个模块要进行端口定义,并说明输入输出口,然后对模块的功能进行行为逻辑描述。
  • Verilog HDL程序的书写格式自由,一行可以写几个语句,一个语句也可以分写多行。
  • 除了endmodule语句外,每个语句和数据定义的最后必须有分号。
  • 可以用“/*.....*/”和“//.......”对Verilog HDL程序的任何部分作注释。一个好的、有使用价值的源程序都应当加上必要的注释,以增强程序的可读性和可维护性。

模块的框架

模块的内容包括I/O声明、I/O说明、内部信号声明和功能定义。

1.I/O声明

模块的端口声明了模块的输入输出端口,其格式如下:

Module 模块名(端口1,端口2,端口3,端口4, …);

2.I/O说明

I/O说明的格式如下:

输入口:input 端口名1,端口名2,…,端口名i; //(共有i个输入口)

输出口:output 端口名1,端口名2,…,端口名j; //(共有j个输出口)

I/O说明也可以写在端口声明语句里,其格式如下:

module module_name(input port1,input port2,…,output port1,output port2… )

3.内部信号声明

在模块内用到的和与端口有关的wire和reg变量的声明,如下所示:

reg [width-1 : 0] R变量1,R变量2 …;

wire [width-1 : 0] W变量1,W变量2 …;

4.功能定义

模块中最重要的部分是逻辑功能定义部分,有3种方法可在模块中产生逻辑。

(1)用“assign”声明语句。

assign a = b c;

这种方法的句法很简单,只需写一个“assign”,后面再加一个方程式即可。例子中的方程式描述了一个有两个输入的与门。

(2)用实例元件。

and and_inst( q, a, b );

采用实例元件的方法在电路图输入方式下,调入库元件。键入元件的名字和相连的引脚即可,表示在设计中用到一个跟与门(and)一样的名为and_inst的与门,其输入端为a、b,输出为q。要求每个实例元件的名字必须是惟一的,以避免与其他调用与门(and)的实例混淆。

(3)用“always”块。

always @(posedge clk or posedge clr) begin //时钟上升沿触发,异步清零

if(clr) q = 0; //清零

else if(en) q = d; //使能赋值

end

采用“assign”语句是描述组合逻辑最常用的方法之一,而“always”块既可用于描述组合逻辑,也可描述时序逻辑。上面的例子用“always”块生成了一个带有异步清除端的D触发器。

“always”块可用很多种描述手段来表达逻辑,例如上例中就用了“if...else”语句来表达逻辑关系。如按一定的风格来编写“always”块,可以通过综合工具把源代码自动综合成用门级结构表示的组合或时序逻辑电路。需要注意的是,如果用Verilog模块实现一定的功能,首先应该清楚哪些是同时发生的,哪些是顺序发生的。

上面3个例子分别采用了“assign”语句、实例元件和“always”块。这3个例子描述的逻辑功能是同时执行的。也就是说,如果把这3项写到一个Verilog模块文件中去,它们的次序不会影响逻辑实现的功能。这3项是同时执行的,也就是并发的。

然而,在“always”模块内,逻辑是按照指定的顺序执行的。“always”块中的语句称为“顺序语句”,因为它们是顺序执行的。请注意,两个或更多的“always”模块也是同时执行的,但是模块内部的语句是顺序执行的。

看一下“always”内的语句,就会明白它是如何实现功能的。“if…else… if”必须顺序执行,否则其功能就没有任何意义。如果else语句在if语句之前执行,功能就会不符合要求。为了能实

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top