1、第3章 基于Verilog HDL语言的设计3.1 Verilog HDL概述概述3.2 门级建模门级建模3.3 数据流建模数据流建模3.4 行为级建模行为级建模3.5 Verilog HDL的可综合设计的可综合设计3.6 Testbench文件与设计文件与设计3.7 Verilog HDL在在ISE软件中设计示例软件中设计示例小结小结习题习题实验项目实验项目3.1 Verilog HDL概述概述硬件描述语言支持层次化的设计、IP Core可重用设计,在EDA工具、FPGA芯片支持下,实现了一种贯穿设计、综合、仿真和下载等多个环节的数字系统快速实现的方法。设计者可以在较为抽象的层次上用HDL对
2、电路进行描述,将繁琐的实现细节交由EDA工具完成,极大地降低了设计复杂度,缩短了开发周期。使用硬件描述语言设计的数字系统,可不依赖特定的厂商和器件,可移植性好。常用的HDL语言有Verilog HDL和VHDL两种。Verilog HDL由GDA公司的Phil Moorby在1983年末首创,1989年CADENCE公司收购了GDA公司,1990年CADENCE公司公开发表了Verilog HDL,成立了OVI(Open Verilog International)组织。随后IEEE制定了 Verilog HDL的IEEE 标准,进一步推动了Verilog HDL的应用。VHDL(VHSIC
3、Hardware Description Language)中的VHSIC是Very High Speed Integerated Circuit的缩写。VHDL是美国国防部为了解决项目的多个承包人的信息交换困难、设计维修困难的问题而提出的,由TI、IBM和INTERMETRICS公司完成,于1987年制定为IEEE标准,即IEEE std 1076-1987LRM87,后又进行一些修改,成为新的标准版本。VHDL和Verilog HDL两种语言的主要功能差别不大,它们的描述能力类似,相比较而言,VHDL较Verilog HDL系统描述能力稍强,Verilog HDL的底层描述能力比VHDL强
4、得多。Verilog HDL拥有广泛的设计群体,成熟的资源比VHDL丰富;完成同一功能描述,Verilog HDL的描述较VHDL更为简洁;Verilog HDL也较易于学习,只要有C语言的编程基础,一般经过23个月的认真学习和实际操作就能掌握,而VHDL设计不很直观,一般需要有半年多的专业培训才能掌握。本节通过用Verilog HDL描述几个简单的数字电路,总结出Verilog HDL的基本特点、设计规则,并建立层次建模的概念,实现Verilog HDL学习的快速入门。3.1.1 几个简单的几个简单的Verilog HDL例子例子例例3-1 设计一个二选一电路,实现表3.1的功能。表 3.1
5、 二选一电路功能 端口说明 功 能 说 明 a b 输入端口 sel 输出端口 c 如果 sel=1,将 b 的值送到输出端口 c 如果 sel=0,将 a 的值送到输出端口 c module mux21(a,b,sel,c);input a,b;input sel;output c;wire c;assign c=sel?b:a;endmodule 从例3-1可以看出:(1)Verilog HDL的程序描述必须位于关键词module和endmodule之间。(2)每个模块必须有一个模块名,如上例的mux21。(3)需要对模块的输入、输出端口进行说明,如上例程序的第二、三、四行表述模块的输入端
6、口是a、b、sel,输出端口是c。(4)模块的变量说明,如程序的第五行声明了一个线网变量c。(5)第六行语句使用条件操作符,实现模块的功能,即判断sel是否等于1,如果等于1,b的值赋给c,否则a 的值赋给c。这段程序描述通过综合工具,可转换成图3.1的门级电路图。图3.1 二选一的电路图 例3-2 用Verilog HDL描述一个用时钟上升沿触发、同步复位的D触发器。module Dflop(d,reset,clk,q);input d,clk;input reset;output q;reg q;always (posedge clk)if(reset=1)q=0;else q=d;end
7、module从例3-2可以看出:(1)模块名是Dflop,输入端口有三个:d、clk和reset,输出端口是q。(2)程序的第五行声明了一个寄存器变量q。(3)always语句描述模块的功能是:在每个clk上升沿时,首先检测reset的值,当reset=1时,输出端口q复位为0,否则将输入值d赋给输出端口q。(4)例3-2实现了图3.2的数字时序电路。图3.2 D触发器 例例3-3 调用例3-2的D触发器实现一个四位的移位寄存器。寄存器存储的数据在移位时钟clock的作用下依次右移,这样构成移位寄存器。移位寄存器既可以存储代码,也可以用来实现数据的串行到并行的转换。电路结构如图3.3所示。图3
8、.3 四位的移位寄存器 调用例3-2设计的D触发器按照图3.3的结构连接,在每次时钟上升沿时,数据依次向右移动一位。经过四个周期时钟信号后,串行输入的四位数据全部移入到移位寄存器中。如果在四个触发器的输出端引出数据,就可实现数据传输的串-并转换。程序如下:module shift_flop(D,reset,clock,Q);/端口声明input D,clock,reset;output3:0 Q;wire 3:0 Q;/变量说明/*调用D触发器Dflop四次,例化名分别命名成u1、u2、u3和u4,同时连接对应的端口,组成四位移位寄存器*/Dflop u1(D,reset,clock,Q3);
9、Dflop u2(Q3,reset,clock,Q2);Dflop u3(Q2,reset,clock,Q1);Dflop u4(Q1,reset,clock,Q0);endmodule 从例3-3可以看到,Verilog HDL很好地支持了“自顶向下”的设计理念。Verilog HDL支持测试激励模块的设计。在仿真软件,如Modelsim(详见第5章)的支持下,将测试模块描述的激励信号传输到待测的功能模块中,在仿真软件中可以观察功能模块的输出情况,从而实现对功能模块的软件测试,及早发现设计中的问题。例例3-4 对例3-3设计的模块编写测试文件。timescale 1ns/100ps/定义测试
10、文件中一个时间的单位是1 ns、时间精度是100 psmodule testbench();/说明测试输入端口reg D;reg clock;reg reset;wire3:0 Q;/例化待测试的移位寄存器shift_flop u1(D,reset,clock,Q);/产生时钟信号 initial begin clock=0;forever#10 clock=clock;end/产生输入信号D,复位信号resetinitialbeginD=1b1;reset=0;#20 reset=1;#15 D=1b0;#20 D=1b1;#100 reset=0;#10$stop;endendmodule
11、 3.1.2 Verilog HDL的基础知识的基础知识1.Verilog HDL的基本结构的基本结构Verilog HDL可以描述数字系统的逻辑功能,描述组合成为一个系统的多个数字模块之间的连接,并建立测试文件等功能。模块(module)是Verilog HDL设计的基本单元,Verilog HDL模块可分为两种类型:一种是功能模块,描述数字电路系统的结构和功能,在EDA工具的支持下转换成电路结构,完成布局、布线、下载,最后在FPGA上实现目标系统,功能模块也可以仅以向仿真软件提供仿真模型为目的,从而对设计方案进行快速验证;另一种是测试模块,为功能模块的测试提供信号激励、输出数据监测,完成功
12、能模块的仿真测试。测试模块的设计详见3.6节。一般而言,模块包括模块名、端口名说明、I/O端口声明、各类型变量声明和模块功能描述等。Verilog HDL模块的一般结构如以下程序所示。module 模块名(input_port1,input_portn,output_port1,output_portN,模块名及模块端口罗列 inout_port1,inout_portM);inputwidth_1-1:0 input_port1;input width_n-1:0 input_portn;module 模块名(input_port1,input_portn,output_port1,outp
13、ut_portN,模块名及模块端口罗列 inout_port1,inout_portM);inputwidth_1-1:0 input_port1;input width_n-1:0 input_portn;outputwidth_1-1:0 output_port1;端口名说明 outputwidth_N-1:0 output_portN;inoutwidth_1-1:0 inout_port1;inoutwidth M-1:0 inout_portM;下面介绍模块中的基本内容。1)模块名、端口名说明格式:module 模块名(端口1,端口2,端口3,端口n);Verilog HDL程序的模
14、块名是必须的,所有程序必须位于关键词module、endmodule之间。为便于工程管理,模块名一般和实现的功能相关,如halfadder(半加器)、top(顶层模块)、testbench(测试模块)等。命名的字符串必须符合Verilog HDL对字符串的规定。端口名说明是一个可选项。(1)当模块与外界没有信息交互、无端口连接时,声明中就不需要无端口名的罗列。如包含了待测模块和激励信号的测试模块,可声明为module testbench();(2)当模块和外界有信息交互时,各端口名必须全部罗列,相互之间用逗号隔开,如module mux21(a,b,sel,c);对于外界环境来说,模块内部是一
15、个“黑盒子”,对模块的例化(instance或称调用)都是通过对模块端口的操作来完成的。2)I/O端口声明所有声明的端口都必须说明端口类型、位宽。端口之间需用逗号隔开,语句用分号结束。根据信号的方向不同,Verilog HDL中的端口类型有以下三种:(1)输入端口:其声明格式为input width-1:0 端口名1,端口名2,端口名n;(2)输出端口:其声明格式为output width-1:0 端口名1,端口名2,端口名n;(3)输入/输出端口:其声明格式为inout width-1:0 端口名1,端口名2,端口名n;width是端口的位宽,如果无位宽说明,系统将默认位宽为1。例如,inp
16、ut7:0 data_in;/一个名为data_in,位宽为8位的输入数据output S,CO;/名为S和CO,位宽均为1位的两个输出数据 3)数据类型说明对于模块端口信号和模块内部信号,需有相应的数据类型说明。Verilog HDL的常用的数据类型分为线网型和寄存器型。线网型表示结构化元件之间的物理连线,寄存器型表示数据的存储单元。为尽可能地反映真实硬件电路的工作情况,可对数字信号的逻辑、强度进行建模,变量的逻辑值有0、1、x和z。x表示未初始化或者未知的逻辑值,z表示高阻状态。Verilog HDL定义了八种信号强度用于判断数字电路中不同强度的驱动源之间的赋值冲突,如表3.2所示。表 3
17、.2 八种信号强度的说明 强度等级 类型 强度 supply 驱动 strong 驱动 pull 驱动 large 存储 weak 驱动 medium 存储 small 存储 highz 高阻 最强 最弱 多个信号驱动同一个线网时,输出信号逻辑强度的建立可以按如下方法判断:(1)逻辑值相同而强度不同的多个信号驱动时,输出信号的逻辑值和强度由强度大的信号决定。(2)逻辑值不同,但强度相同的多个信号驱动时,输出信号的逻辑值可能会得到不定值。4)模块功能说明模块逻辑功能的描述是模块中最重要的部分,可根据设计需要选用以下四类常用方法:(1)用连续赋值语句“assign”进行数据流建模。描述数据在各个寄
18、存器、逻辑门之间的传递,详见3.3节。(2)调用已设计好的子模块,组合成更复杂的系统。Verilog HDL支持“自顶向下”的设计方法,大型的、复杂的数字系统逐层分解成多个简单的模块构成,在分别完成各个子模块设计后,通过上层模块例化(或称调用)低层模块的方式,完成目标系统的组合。(3)使用结构说明语句“always”、“initial”可以进行变量初始化、组合电路和时序电路块的描述,具体语法详见3.4节。(4)编写任务(task)和函数(function),对重复使用的功能进行描述,为复杂系统的设计提供支持,具体语法详见3.4节。2模块的例化模块的例化通过模块的例化(或称调用),Verilog
19、 HDL可以支持层次化设计,实现“自顶向下”的设计思路,模块例化的基本格式为();根据被调用的低层模块与上层模块的端口连接方式描述的不同,有两种例化方法:(1)按端口顺序连接:低层模块定义时声明的端口顺序与上层模块相应的连接端口顺序保持一致,其格式为模块名 例化名(PORT_1,PORT_2,PORT_N);(2)按端口名称连接:被调用的低层模块和上层模块是通过端口名称进行连接,其格式为模块名 例化名(.port_1(PORT_1),.port_2(PORT_2),.port_n(PORT_N);其中:port_1,port_2,port_n表示被调用模块设计声明的各个端口;PORT_1,PO
20、RT_2,PORT_N表示上一层模块调用时对应的端口名称。这种连接端口的顺序可以是任意的,只要保证上层模块的端口名和被调用模块端口的对应即可。如果被调用模块有不需要连接的端口,该端口可悬空写成.port_n(),也可将此端口忽略。例如,port_2不需要和外界连接,可以写成:模块名 例化名(.port_1(PORT_1),.port_2(),.port_n(PORT_N);或者模块名 例化名(.port_1(PORT_1),.port_n(PORT_N);/*注意,port_2虽然未写出,但其位置仍然保留*/当被调用模块有较多端口时,根据端口名称进行信号连接,可避免因记错端口顺序而出错,并且在
21、被调用模块因修改使得端口顺序发生变化时,只要端口名称、功能不变,上层模块调用就可以不更改。在实际应用中,可根据设计的复杂程度和设计习惯来选择例化的方法。例3-5 通过调用半加器模块、或门模块来实现一位全加器。半加器模块的端口如图3.4所示。图3.4 半加器模块的端口(1)设计半加器。module halfadder(A,B,CO,S);input A,B;/输入两个1位的数据作为加数、被加数 output S;/加法器输出的和output CO;/加法器输出的进位wire S,CO;assign S=A B;assign CO=A&B;endmodule(2)设计一位全加器。根据数字逻辑电路关
22、系,调用半加器、或门组成一位全加器,其电路连接图如图3.5所示。图3.5 全加器电路连接图 Verilog HDL可用以下两种方法描述:方法一:采用按端口顺序连接module fulladder(a,b,co_in,co_out,s);input a,b,co_in;output co_out,s;halfadder u1(a,b,co_temp1,s_temp);halfadder u2(s_temp,co_in,co_temp2,s);or u3(co_out,co_temp1,co_temp2);endmodule 方法二:采用按端口名称连接module fulladder(a,b,co
23、_in,co_out,s);input a,b,co_in;output co_out,s;halfadder u1(.A(a),.B(b),.CO(co_temp1),.S(s_temp);halfadder u2(.A(s_temp),.B(co_in),.CO(co_temp2),.S(s);or u3(co_out,co_temp1,co_temp2);endmodule 3.Verilog HDL基本概念基本概念1)词法约定Verilog HDL中的基本词法约定与C语言类似,可以有空白、注释、分隔符、数字、字符串、标识符和关键词等,其中关键词全是小写字母。(1)注释:为加强程序的可读
24、性和文档管理,设计程序中应适当地加入注释内容。注释有两种方式:单行注释和多行注释。单行注释以“/”开始,只能写在一行中。例如,assign c=a+b;/c等于a,b的和 多行注释以“/*”开始,以“*/”结束,注释的内容可以跨越多行,例如,assign c=a+b;/*c等于a,b的和,本语句可综合成一个加法器,实现加法的组合逻辑*/(2)标识符(identifier):用于定义模块名、端口名、连线、信号名等。标识符可以是任意一组字母、数字、$符号和_(下划线)符号的组合,但标识符的第一个字符必须是字母或者下划线,字符数不能多于1024个。此外,标识符区分大、小写。例如,state,Stat
25、e /这两个标识符是不同的2and,&write /非法标识符(3)空白符:由空格(b)、制表符(t)和换行符定义而成,除了出现在字符串里,Verilog HDL中其它位置的空白符仅仅用于分隔标识符,在编译阶段被忽略。2)数据类型在程序设计中,数据有常量和变量两种,下面分别进行介绍。(1)常量:是指在程序运行中,其值不能改变的量。数字:其表达方式为说明:用十进制表示的数字的位数,如果缺省,位宽由具体机器系统决定(至少为32位)。:可以用四种进制表示:二进制(b或B)、八进制(o或O)、十进制(d或D)、十六进制(h或H)。缺省时为十进制。:可以是所选进制表述的任意有效数字,包括不定值x和高阻态
26、z。当位宽大于指定的大小时,截去高位。例如,8b11001100/位宽为8的二进制数,b表示二进制h1f23 /十六进制数,采用机器的默认位宽2b110 x/表示2b0 x,因为当数值大于指定的大小时,截去高位16h1z0 x/位宽为16位的十六进制数,其值的二进制表示为16b0001zzzz0000 xxxx可在数字之间使用下划线“_”对数字进行分隔,下划线只增加数字的可读性,在编译阶段将被忽略,如8b1100_1100。参数型(parameter):可以用parameter为关键词,指定一个标识符(即名字)来代表一个常数,参数的定义常用在信号位宽定义,延迟时间定义等位置,以增加程序的可读性
27、,方便程序的修改,其格式为parameter 标识符1=表达式1,标识符2=表达式2,标识符n=表达式n;这里的表达式可以是常数,也可以是以前定义过的标识符。例如,parameter width=8;/定义了一个常数参数inputwidth-1:0 data_in;/表示输入信号data_in的位宽为8parameter a=1,b=3;/定义了两个常数参数parameter c=a+b;/表示c的值是前面定义的a、b值的和(2)变量:指在程序运行中,其值可以改变的量。Verilog HDL中常用的三种数据类型为wire型、reg型和memory型,其它数据类型的说明请查阅Verilog HD
28、L的相关手册。线网wire型变量:wire型线网变量表示硬件单元之间的连接,它的值由驱动元件的值决定。如果没有驱动元件连接到线网,线网的缺省值为z。Verilog HDL模块端口信号的数据类型如无定义,默认为wire型,其定义格式为wire width-1:0 变量名1,变量名2,变量名n;说明:width-1:0指明了变量的位宽,缺省此项时默认变量位宽为1。wire为关键词,多个变量名之间用逗号隔开。模块的输入/输出信号的数据类型默认为wire型。例如,wire 7:0 a,b;/位宽为8的wire型变量a和bwire c;/wire型变量c,位宽为1 reg型:reg型寄存器变量表示一个抽
29、象的数据存储单元,只能在initial语句和always语句中被赋值。寄存器型变量的默认值是不定值x。其定义格式为regwidth-1:0 变量名1,变量名2,变量名n;例如,reg 7:0 b,c;/两个位宽为8的reg型变量b和creg a;/reg型变量a,位宽为1 memory型:memory型数据常用于寄存器文件,以及ROM、RAM的建模等。memory型数据是将reg型变量进行地址扩展而得到的,其格式为regn-1:0 存储器名N-1:0;/定义位宽为n,深度为N的寄存器组例如,reg7:0 mem255:0;/每个寄存器位宽为8,共有256个寄存器的寄存器组对一组存储单元进行读写
30、,必须指定该单元的地址,如对上例的mem寄存器的第200个存储单元进行赋0值的操作语句为mem200=0;/对存储器mem的第200个存储单元赋值为0需要注意 memory型数据和reg型数据的区别。例如,reg mem N-1:0;/由N个位宽为1的寄存器组成的寄存器组memreg N-1:0 a;/一个N位的寄存器变量a 3.1.3 Verilog HDL的描述层次的描述层次根据对电路描述的抽象程度不同,Verilog HDL描述有四个层次。(1)行为级或算法级:这是Verilog HDL支持的最高抽象级别,在这一级别上设计者关注算法的实现,不关心具体的硬件实现细节,几乎可以使用Veril
31、og HDL提供的所有语句。(2)数据流级:通过描述模块内部数据流的情况来描述该逻辑单元的功能,在这一级别上设计者关注数据的处理及其如何在线网上和寄存器间的传递。一般情况下,寄存器传输级(RTL)描述指的是能够通过综合工具转化为门级电路的行为级描述和数据流级描述。(3)门级:调用已设计好的逻辑门基本单元(原语),如与门、或门、异或门等,描述逻辑门之间的连接,构成电路。(4)开关级:这是Verilog HDL支持的最低抽象层次,通过描述器件中的晶体管、存储节点及其它们的互联来设计模块。由于开关级描述的应用较少,本章将从门级建模、数据流级建模和行为级建模等三个层次对Verilog HDL的语法进行
32、讨论。3.2 门门 级级 建建 模模3.2.1 门的类型门的类型Verilog HDL定义了两类基本的逻辑门:与/或门类(and/or)、缓冲/非门类(buf/not),称为预定义的逻辑门,在使用预定义的逻辑门原语例化逻辑门时,可以直接使用相关原语,无需再次声明定义。预定义逻辑门调用时,例化名可选,其格式为 (端口列表);例如,调用与门可以写成or or1(out,in1,in2);或 or(out,in1,in2);1与与/或门类或门类(见表见表3.3所示所示)说明:(1)与/或门类都有一个输出端和多个输入端,门端口列表中的第一个端口必定是输出端口,其它是输入端口。(2)在门的例化调用中,如
33、果输入端口的个数超过两个,只需将输入端口直接排列在端口列表中即可,Verilog HDL根据输入端口数自动选择合适端口的逻辑门。例如,设输出端口为out,输入端口为in1、in2、in3和in4。and u1(out,in1,in2);/二输入与门xor x1(out,in1,in2,in3,in4);/四输入异或门,输入端口数目超过2个(3)基本门的真值表如表3.4所示。表表3.4 基本门的真值表基本门的真值表(4)如果输入端口多于两个,则可以通过重复使用两输入真值表来计算输出的值。2缓冲缓冲/非门类非门类Verilog HDL提供了缓冲器和非门原语,其逻辑符号和功能如表3.5所示。说明:(
34、1)缓冲/非门类逻辑门具有一个输入,多个输出,端口列表的最后一个端口是输入端口,其它是输出端口。(2)如果输出端口多于一个,只需将所有的输出端口排列在端口列表中,Verilog HDL可以根据端口自动选择合适的逻辑门。例如,设in是输入端口,out、out1、out2和out3是输出端口。buf (out,in);/单输出缓冲门not (out,in);/单输出非门buf b2(out1,out2,out3,in);/多输出缓冲门,例化名为b2not n2(out1,out2,in);/多输出非门,例化名为n2(3)缓冲器和非门的真值表如表3.6所示。(4)Verilog HDL还支持四个带控
35、制的条件缓冲器和条件反相器,它们有输出、输入和控制三个引脚,其功能和符号见表3.7,相关真值表见表3.8。例如,设out是输出端口,in是输入端口,control是控制端口。bufif1 u1(out,in,control);bufif0 u2(out,in,control);notif1 u3(out,in,control);notif0 u4(out,in,control);在调用四种条件缓冲器和条件反相器时,注意端口罗列的顺序规则。3.2.2 实例数组实例数组(Array of Instances)在实际应用中,常会对某种逻辑门进行多次调用,实现多位宽数据的逻辑运算,这可以通过实例数组的
36、方式来表述,以简化书写,其格式为 (端口列表);例3-6 实现两个3位数据的或运算。module or3(in1,in2,out);input 2:0 in1,in2;output 2:0 out;wire 2:0 out;or u2(out2,in12,in22);or u2:0(out,in1,in2);or u1(out1,in11,in21);endmodule or u0(out0,in10,in20);语句等价3.2.3 应用举例应用举例下面用预定义逻辑门原语设计三个数据的奇偶校验位电路。由于信道的噪声干扰、传输中断等原因容易使传送的数据产生误码,奇偶校验是比较常用的检错码。它是一
37、种通过增加冗余位使得码字中1或0的个数恒为奇数或偶数的方法。例例3-7 设输入是A、B、C,输出的校验位码字是F,其真值表如表3.9所示。可以使用异或逻辑门来实现这个电路,其奇偶校验位电路如图3.6所示。表3.9 奇偶校验位的真值表 图3.6 三个数据的奇偶校验位电路 逻辑图与Verilog HDL的描述有一一对应的关系。奇偶校验位电路的Verilog HDL门级描述如下:module CRC_test(A,B,C,F);/端口说明input A,B,C;output F;wire temp;/内部线网temp声明xor(temp,B,C);/调用两输入的异或门xor (F,temp,A);e
38、ndmodule3.2.4 门延迟门延迟1上升、下降和关断延迟上升、下降和关断延迟 在Verilog HDL中,定义了三种输入到输出的延迟:(1)上升延迟:逻辑门的输出从低电平0、未知态x、高阻态z变化成为高电平1所需的时间。(2)下降延迟:逻辑门的输出从高电平1、未知态x、高阻态z变化成低电平0所需的时间。(3)关断延迟:逻辑门的输出从高电平1、低电平0、未知态x变化成高阻态z所需的时间。在Verilog HDL中,用户可以使用表3.10中的三种方法指定逻辑门延时。表 3.10 门的三种延时指定方法 说 明 例 子 指定一种延时值,所有类型的延时都是这个值 格式:name#(delay_ti
39、me)(port declare);and#5(out,a,b);/所有延迟均为 5 指定两种延时值:上升延时和下降延时,两者中较小者为关断延时 格式:name#(risin_time,fall_time)(port_declare);or#(5,6)(out,c,d);/*或门的上升延时是 5,下降延时是 6,关断延时是 5*/指定三个延时值,即上升延时、下降延时和关断延时 格 式:name#(rising_time,fall_time,turnoff_time)(port _declare);xor#(5,7,8)(out,in1,in2);/*异或门的上 升延时是 5,下降延时是 7,关
40、断 延时是 8*/用户如未指定延迟值,默认延时值是 0 2最小最小/典型典型/最大延迟最大延迟由于受集成电路制造工艺过程的影响,真实器件的延时会有一个变化的范围。在Verilog HDL中,除了支持上述的三种延时以外,还可以分别指定每种延时的最小值、最大值和典型值。(1)最小值(min_delay_time):逻辑门所具有的最小延时。(2)典型值(typical_delay_time):逻辑门所具有的典型延时。(3)最大值(max_delay_time):逻辑门所具有的最大延时。格式:#(min_delay_time:typical_delay_time:max_delay_time)(por
41、t declare);用户可以在仿真一开始就指定具体选用哪一种延时值(最大值/典型值/最小值),以建立不同的仿真模型。用户也可以在仿真过程中控制延迟值的使用,具体的控制方法与使用的仿真器和操作系统有关。例如,and#(4:5:6)(out,a,b);/*只声明了一个延时时间,所有延时的最小值=4,典型值=5,最大值=6*/or#(4:5:6,5:6:7)(out,c,d);/*声明了两个延时,上升延时的最小值=4,典型值=5,最大值=6;下降延时的最小值=5,典型值=6,最大值=7*/xor#(4:5:6,6:7:8,7:8:9)(out,in1,in2);/*声明了三个延时,上升延时的最小值
42、=4,典型值=5,最大值=6下降延时的最小值=6,典型值=7,最大值=8关断延时的最小值=7,典型值=8,最大值=9*/3.3 数数据据流流建建模模 3.3.1 连续赋值语句连续赋值语句连续赋值语句常用于数据流行为建模,以assign为关键词,操作符是“=”。assign赋值语句执行将数值赋给线网,可以完成门级描述,也可从更抽象的角度对线网电路进行描述,多用于组合逻辑电路的表述,其格式为assign 赋值目标线网=表达式;例如,assign a=b|c;/两输入的或门assign c,sum3:0=a3:0+b3:0+c_in;/*一个四位的加法器,a、b是加数和被加数,c_in是进位,sum
43、、c分别是相加后的和、进位*/assign c=max(a,b);/调用了求最大值的函数max,将函数返回值赋给c说明:(1)式子左边的“赋值目标线网”只能是线网变量,不能是寄存器变量。(2)式子右边表达式的操作数可以是线网、寄存器,也可以是函数调用。(3)一旦等式右边任何一个操作数发生变化,右边的表达式就会立刻被重新计算,再进行一次新的赋值。(4)assign可以使用条件运算符进行条件判断后再赋值,如下述语句:assign data_out=sel?a:b;/*如果sel等于1,将a赋给data_out,否则将b赋给data_out,实现一个二选一的电路*/(5)可用赋值延时控制对线网赋予新
44、值的延时时间,延时值位于关键词assign的后面,但标注的延时时间在编译过程中将被忽略。assign#10 data_out=data_in1&data_in2;/*计算data_in1&data_in2的值,延迟10个时间单位赋给data_out,时间单位由timescale给定*/3.3.2 表达式、运算符和操作数表达式、运算符和操作数 分 类 运 算 运 算 符 优先级 逻辑/按位运算符 单目运算!,&乘、除、取模*,/,算术运算符 加、减,移位运算符 移位 关系运算符 关系,=等式运算符 等价=,!=,=,!=&,&,按位/缩减运算符 缩减|,|,&逻辑运算符 逻辑|条件运算符 条件?
45、:最高 最低 表表3.11 运算符的分类和优先级运算符的分类和优先级 根据参加运算的操作数的数目,运算符可分为(1)单目运算符:对一个操作数进行运算的运算符,如clock=clock。(2)双目运算符:对两个操作数进行运算的运算符,如a=b&c。(3)三目运算符:对三个操作数进行运算的运算符,如D_out=condition?D_in1:D_in2。1算术运算符算术运算符算术运算符有加法(+)、减法(-)、乘法(*)、除法(/)和取模(%)。例如,设a=4b0101,b=4b0010a+b /a和b相加,等于4b0111a/b /a除以b,等于4b0010,余数部分舍弃,取整a%b /a对b取
46、模,即求a、b相除的余数部分,结果等于1注意:在算术运算时,如有一个操作数是不定值x,则运算结果将不能得到确定数值。如果使用“+”、“-”运算符作为操作数的正、负表示时,它们的优先级比双目运算符更高。2.逻辑运算符逻辑运算符逻辑运算符有逻辑与(&)、逻辑或(|)和逻辑非(!)。说明:(1)“&”和“|”是双目运算符,“!”是单目运算符。(2)逻辑运算符的计算结果是一个一位的值,可以是:逻辑假(0)、逻辑真(1)和不确定(x)。(3)如果操作数为具体数值时,操作数不等于0,等价于逻辑真(1);操作数等于0,等价于逻辑假(0);操作数的任何一位为不定值x或者高阻态z,等价于不定值。例如,设a=2,
47、b=0a&b /等于0,相当于(逻辑1&逻辑0)a|b /等于1,相当于(逻辑1|逻辑0)!a /等于0,相当于逻辑1取反(a=3)&(b=0)/*等于0,相当于两个表达式是否成立(为真),即如果a=3成立,则(a=3)为逻辑1,否则为逻辑0*/x&a /等于x,相当于(x&逻辑1)3按位运算符按位运算符按位运算符有取反()、与(&)、或(|)、异或()和同或(,)。说明:(1)取反运算是单目运算符,其余是双目运算符。(2)按位运算是对操作数中的每一位进行按位操作。若两个数的位宽不相同,系统先将两个操作数右对齐,较短的操作数左端补0,使得两个操作数位宽相同,然后再按位运算。(3)注意按位运算和
48、逻辑运算的差别,逻辑运算结果是一个一位的逻辑值,按位运算产生一个与较长位宽操作数等宽的数值。例如,设a=4b0011,b=4b1010,c=3b011,d=4b11x0a /按位取反,结果等于4b1100b&c /按位与运算,结果等于4b0010a d /按位同或运算,结果等于4b00 x0a&b /按位与运算,结果等于4b0010下句与前句比较:a&b /逻辑与运算,等价于 1&1,结果等于1 4关系运算符关系运算符关系运算符包括大于()、小于(=)、小于等于(b /结果等于逻辑值1a b /*由于算术运算优先级较高,先进行13 a的计算,得到3,再和b进行比较,结果等于逻辑值1*/13 (
49、ab)/*由于括号表明了关系运算的优先级,ab成立,结果是真值为1,所以算术结果等于12*/5等式运算符等式运算符等式运算符包括逻辑等(=)、逻辑不等(!=)、case等(=)、case不等(!=)。说明:(1)若两个操作数位宽不等,先将两个操作数右对齐,用0填充较短数的左边。(2)逻辑等(=)和逻辑不等(!=)中,如果两操作数中某一位是不确定的,则返回值是x;在逻辑等运算时,如果两个数相同,返回逻辑值1,否则返回逻辑0。逻辑不等运算,反之同理。例如,设a=4b1010,b=4b1100,d=4b101xa=b;/结果为逻辑值0a!=b;/结果为逻辑1a=d;/结果为逻辑x(3)case等(=
50、)、case不等(!=)与逻辑等式运算符不同。在对两个操作数进行逐位比较时,即使有x、z位,也要进行精确比较。在case等运算中,只有在两者完全相等的情况下结果为1,否则为0。case等运算符的结果不可能为x。例如,设a=4b1010,b=4b1xzz,c=4b1xzz,d=4b1xzxa=b;/结果为逻辑值0b=c;/结果为逻辑值1(两个数每一位都相同,包括x、z)b=d;/结果为逻辑值0 b!=d;/结果为逻辑值1 6缩减运算符缩减运算符缩减运算符包括缩减与(&)、缩减与非(&)、缩减或(|)、缩减或非(|)、缩减异或()、缩减同或()。这类操作符将对操作数由左向右进行操作,它们的运算规则