模块的结构、数据类型、变量和基本运算符号
3.1.模块的结构
Verilog的基本设计单元是“模块”(block)。一个模块是由两部分组成的,一部分描述接口,另一部分描述逻辑功能,即定义输入是如何影响输出的。下面举例说明:图1 模块示例
m
请看上面的例子: 程序模块旁边有一个电路图的符号。在许多方面,程序模块和电路图符号是一致的,这是因为电路图符号的引脚也就是程序模块的接口。而程序模块描述了电路图符号所实现的逻辑功能。以上就是设计一个简单的Verilog程序模块所需的全部内容。从上面的例子可以看出,Verilog结构位于在module和endmodule声明语句之间,每个Verilog程序包括四个主要部分:端口定义、I/O说明、内部信号声明、功能定义。
3.1.1、模块的端口定义
模块的端口声明了模块的输入输出口。其格式如下:
module 模块名(口1,口2,口3,口4, ………);
…….
endmodule
模块的端口表示的是模块的输入和输出口名,也就是它与别的模块联系端口的标识。在模块被引用时,在引用的模块中,有些信号要输入到被引用的模块中,有的信号需要从被引用的模块中取出来。在引用模块时其端口可以用两种方法连接:
1)在引用时,严格按照模块定义的端口顺序来连接,不用标明原模块定义时规定的端口名,举例说明如下:
模块名 实例化名( 连接端口1信号名, 连接端口2信号名,连接端口3信号名,….,,,);
2)在引用时用“.”标明原模块定义时规定的端口名,举例说明如下:
模块名 实例化名(.端口1名( 连接信号1名),.端口2名( 连接信号2名),….,,,);
这样表示的好处在于可以用端口名与被引用模块的端口对应,不必严格按端口顺序对应,提高了程序的可读性和可移植性。
3.1.2、模块内容
模块的内容包括I/O说明、内部信号声明、功能定义。
3.1.2.1、I/O说明的格式如下:
输入口: input [信号位宽-1 :0] 端口名1;
input [信号位宽-1 :0] 端口名2;
………;
input [信号位宽-1 :0] 端口名i; //(共有i个输入口)
输出口: output [信号位宽-1 :0] 端口名1;
output [信号位宽-1 :0] 端口名2;
………;
output [信号位宽-1 :0] 端口名j; //(共有j个输出口)
输入/输出口:
inout [信号位宽-1 :0] 端口名1;
inout [信号位宽-1 :0] 端口名2;
………;
inout [信号位宽-1 :0] 端口名k; //(共有k个双向总线端口)
I/O说明也可以写在端口声明语句里。其格式如下:
module module_name(input port1,input port2,…
output port1,output port2… );
3.1.2.2、内部信号说明:
在模块内用到的和与端口有关的wire 和 reg 类型变量的声明。如:
reg [width-1 : 0] R变量1,R变量2 。。。。;
wire [width-1 : 0] W变量1,W变量2 。。。。;
………..
3.1.2.3、功能定义:
模块中最重要的部分是逻辑功能定义部分。有三种方法可在模块中产生逻辑。
1)用“assign”声明语句,如: assign a = b & c;
2)实例化模块,如: and u1( q, a, b );
3)用“always”块
如:always @(posedge clk or posedge clr)
begin
if(clr) q <=>=>
else if(en) q <=>=>
end
采用“assign”语句是描述组合逻辑最常用的方法之一。而“always”块既可用于描述组合逻辑也可描述时序逻辑。上面的例子用“always”块生成了一个带有异步清除端的D触发器。“always”块可用很多种描述手段来表达逻辑,例如上例中就用了if...else语句来表达逻辑关系。如按一定的风格来编写“always”块,可以通过综合工具把源代码自动综合成用门级结构表示的组合或时序逻辑电路。
3.1.3、理解要点:
如果用Verilog模块实现一定的功能,首先应该清楚哪些是同时发生的,哪些是顺序发生的。上面分别采用了“assign”语句、实例元件和“always”块,描述的逻辑功能是同时执行的。也就是说,如果把这三项写到一个 VeriIog 模块文件中去,它们的次序不会影响逻辑实现的功能。这三项是同时执行的,也就是并发的。
然而,在“always”模块内,逻辑是按照指定的顺序执行的。“always”块中的语句称为“顺序语句”,因为它们是顺序执行,所以“always”块也称作“过程块”。请注意,两个或更多的“always”语句块,它们是同时执行的,而模块内部的语句是顺序执行的。 看一下“always”块内的语句,你就会明白它是如何实现功能的。 if..else… if必须顺序执行,否则其功能就没有任何意义。如果else语句在if语句之前执行,其功能就会不符合要求!为了能实现上述描述的功能,“always”语句块内部的语句将按照书写的顺序执行。
在Verilog 模块中所有