24Verilog数名系统设计教程(率2版)wireoutw;initial1/把寄存器变量初始化为一确定值beginain = Osbin = 0;select =0;clock = 0;endalways#50clock=clock;//产生一个不断重复的周期为100个的时钟信号clockalways @(posedge clock)begin//($random为系统任务,会产生一个随机数#lain=【$tandom)%2;//产尘随机的位信号流ain和bin,%2为模2运算#3bin=←$random)%2+1/分别延迟1和3个时间单位后产生随机的位信号流ain和binendalways #10000select=!select:1/产生周期为10000个单位时间的选通信号变化/ /..**muxtwom (.out (outw),.a(ain),.b(bin),-sl(select));/*实例引用多路器,并加人测试信号流,以观察模块的输出out。其中,muxtwo是已经定义的(行为的或结构的)模块,m表示在本测试模块中有一个名为m的muxtwo的模块,其四个端口分别为:out(),.a(),.b(),.sl(),*,”表示端口,后面紧跟端口名,其名称必须与muxtwo模块定义的端口名一致:小括号内的信号名为与该端口连接的信号线名,可以用别的名,但必须在本模块中定义,说明其类型。* /endmodule其中muxtwo可以是行为模块,也可以是布尔逻辑表达式或门级结构模块。模块t可以对muxtwo模块进行逐步深入的完整测试。这种测试可以在功能(即行为)级上进行,也可以在逻辑网表(逻辑布尔表达式)和门级结构级上进行。它的分别称为前(RTL)仿真、逻辑网表仿真和门级仿真。如果门级结构模块与具体的工艺技术对应起来,并加上布局布线引人的延迟模型,此时进行的仿真称为布线后仿真,这种仿真与实际电路情况非常接近。可以通过运行仿真器,并观察输人/输出波形图来分析设计的电路模块的运行是否正确。小结通过上面众多例子可以看到:(1)VerilogHDL程序是由模块构成的。每个模块的内容都是位于module和endmod-ule两个语句之间。每个模块实现特定的功能。(2)模块是可以进行层次嵌套的。正因为如此,才可以将大型的数字电路设计分割成不同的小模块来实现特定的功能
1-第2章Verilog络法的基本横会25(3)如果每个模块都是可以综合的,则通过综合工具可以把它们的功能描述全都转换为最基本的逻辑单元描述,最后可以用一个上层模块通过实例引用把这些模块连接起来,把它们整合成一个很大的逻辑系统。(4)Verilog模块可以分为两种类型:一种是为了让模块最终能生成电路的结构,另一种只是为了测试所设计电路的逻辑功能是否正确。(5)每个模块要进行端口定义,并说明输入、输出口,然后对模块的功能进行描述。(6)VerilogHDL程序的书写格式自由,一行可以写几个语句,一个语句也可以分写多行。(7)除了endmodule语句外,每个语句和数据定义的最后必须有分号。(8)可以用/*…..…*/和//…··对VerilogHDL程序的任何部分作注释。一个好的、有使用价的源程序都应当加上必要的注释,以增强程序的可读性和可维护性。思考题1.Verilog语言有什么作用?2.构成模块的关键词是什么?3.为什么说可以用Verilog构成非常复杂的电路结构?4.为什么可以用比较抽象的描述来设计具体的电路结构?5.是否任意抽象的符合语法的Verilog模块都可以通过综合工具转变为电路结构?6.传么制综合?7.综合是由什么工具来完成的?8、返过综合产生的是什么?产生的结果有什么用处?9.仿真是什么?为什么要进行仿真?10.仿真可以在几个层面上进行?每个层面的仿真有什么意义?11、模块的端口是如何描述的?12.在引用实例模块的时候,如何在主模块中连接信号线?13.如何产生连续的周期性测试时钟?14.如果不用initial块,能否产生测试时钟?15。从本讲的简单例子,是否能明白lways快与initia块有什么不同?16.为什么说Verilog可以用来设计数字逻辑电路和系统?
第3章模块的结构、数据类型、变量和基本运算符号概述在本章中将详细地学习Verilog语法中关于模块的结构、数据类型、变量和基本运算符号等语法要素。这些内容看起来简单,有许多语法现象和C语言也很类似,但有许多地方则是完全不同的。在学习中要注意不同点,并有意识地把新概念与硬件结构和测试联系起来,再通过理解物理意义,牢牢地记住。3.1模块的结构Verilog的基本设计单元是“模块”(block)。一个模块是由两部分组成的,一部分描述接口,另一部分描述逻辑功能,即定义输入是如何影响输出的。图3.1是模块结构组成图。下面举例说明。图中的程序模块(见图3.1(a))旁边有一个电路图的符号(见图3.1(b))。在许多方面,程序模块和电路图符号是一致的,这是因为电路图符号的引脚也就是程序模块的接口。而程序模块描述了电路图符号所能实现的逻辑功能。上面的Verilog设计中,模块中的第二、第三行说明接口的信号流向,第四、第五行说明了模块的逻辑功能。以上就是设计一个简单的Veril-og程序模块所需的全部内容。module back (a,b,c,d):input a,b;outpute,d;assign c-a I b;dassignd=a&b;endmodulk(a)程序模块(b)电路图符号图3.1模块结构的组成从这一例子可以看出,Verilog结构位于在module和endmodule声明语句之间,每个Verilog程序包括4个主要部分:端口定义、1/O说明、内部信号声明和功能定义。3.1.1模块的端口定义模块的端口声明了模块的输入输出口。其格式如下:module模块名(口1,口2.口3,口4,......);模块的端口表示的是模块的输入和输出口名,也就是说,它与别的模块联系端口的标识
27第3章慎块的结构、数格典型、变量和基降继算格号在模块被引用时,在引用的模块中,有些信号要输人到被引用的模块中,有的信号需要从被引用的模块中取出来。在引用模块时其端口可以用两种方法连接:(1)在引用时,严格按照模块定义的端口顺序来连接,不用标明原模块定义时规定的端口名,例如:模块名(连接端口1信号名,连接端口2信号名,连接端口3信号名,**):(2)在引用时用“,”符号,标明原模块是定义时规定的端口名,例如:模块名(.端口1名(连接信号1名),端口2名(连接信号2名),);这样表示的好处在于可以用端口名与被引用模块的端口相对应,而不必严格按端口顺序对应,提高了程序的可读性和可移植性。例如:MyDesignMKMl(.sin(SerialIn),.pout(ParallelOut),**.),其中,.sin和.pout都是M1的端口名,而Ml则是与MyDesignMK完全一样的模块。MyDesignMK已经在另一个模块中定义过,它有两个端口,即sin和pout。与sin口连接的信号名为Serialn,与pout端口连接的是信号名为ParallelOut。3.1.2模块内容模块的内容包括I/O说明、内部信号声明和功能定义。1.1/0说明的格式input[信号位宽一1:0]端口名1;输人口:input[信号位宽一1,0]端口名2;:1/(共有1个输人口)input[信号位宽一1.0]端口名i输出口:output[信号位宽一1.0]端口名1;output[信号位宽一1:0]端口名2,主1/(共有1个输出口)output[信号位宽一1,o]端口名it输入/输出口:inout【信号位宽一1:0]端口名1;inout【信号位宽一1:0]端口名2;:1/(共有k个双向总线端口)inout[信号位宽一1.0]端口名k;I/O说明也可以写在端口声明语句里。其格式如下:module tnodule_name(input portl,input port2,**output portl,output port2... :2.内部信号说明在模块内用到的和与端口有关的wire和reg类型变量的声明。如:reg[width-1:0]R变量1,R变量2,wire[width-1:o]W变量1,W变量2;
28Verilog数字系晚银什教程(第2服):3.功能定义模块中最重要的部分是逻辑功能定义部分。有3种方法可在模块中产生逻辑。(1)用assign"声明语句如:assigna=b&c这种方法的句法很简单,只需写一个“assign”,后面再加一个方程式即可。例中的方程式描述了一个有两个输人的与门。(2)用实例元件如:and#2ul(g,a,b);采用实例元件的方法像在电路图输入方式下调入库元件一样,键入元件的名字和相连的引脚即可。这表示在设计中用到一个跟与门<and)一样的名为ul的与门,其输入端为a、b,输出为q。输出延迟为2个单位时间。要求每个实例元件的名字必须是唯一的,以避免与其他调用与门(and)的实例混淆。(3)用always"块如always@(posedgeclkorposedgeclr),beginif(elr)q<=0;else if(en) q = d;end采用"assign”语句是描述组合逻辑最常用的方法之。而“always"块既可用于描述组合逻辑,也可描述时序逻辑。用always”块的例子生成了一个带有异步清除端的D触发器。“always"块可用很多种描述手段来表达逻辑,例如上例就用了ifelse语句来表达逻辑关系。如按一定的风格来编写“always"块,可以通过综合工具把源代码自动综合成用门级结构表示的组合或时序逻辑电路。3.1.3理解要点如果用Verilog模块实现一定的功能,首先应该清楚哪些是同时发生的,哪些是顺序发生的。上面3.1.2节中的(1)(3)的3个例子分别采用了“assign"语句、实例元件和always块。这3个例子描述的逻辑功能是同时执行的。也就是说,如果把这3项写到一个Verilog模块文件中去,它们的顺序不会影响实现的功能。这3项是同时执行的,也就是并发的。然而,在"always"模块内,逻辑是按照指定的顺序执行的。“always”块中的语句称为“顺序语句”,因为它们是顺序执行的。所以,“always”块也称为“过程块”。请注意,两个或更多的“always"模块都是同时执行的,而模块内部的语句是顺序执行的。看一下“always”内的语句,就会明白它是如何实现功能的。ifelseif必须顺序执行,否则其功能就没有任何意义。如果else语句在if语句之前执行,其功能就会不符合要求。为了能实现上述描述的功能,“al-ways”模块内部的语句将按照书写的顺序执行。3.1.4要点总结Verilog的初学者一定要深入理解并记住:(1)在Verilog模块中所有过程块(如:initial块、always块)、连续赋值语句、实例引用都是并行的;(2)它们表示的是一种通过变盘名互相连接的关系: