《Verilog HDL项目式教程》全套教学课件_第1页
《Verilog HDL项目式教程》全套教学课件_第2页
《Verilog HDL项目式教程》全套教学课件_第3页
《Verilog HDL项目式教程》全套教学课件_第4页
《Verilog HDL项目式教程》全套教学课件_第5页
已阅读5页,还剩366页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

项目1

VerilogHDL综述项目2数据流建模项目3结构化建模项目4行为建模项目5状态机建模项目6数字电路设计举例项目7简易CPU设计全套可编辑PPT课件

本课件是可编辑的正常PPT课件任务1.1

VerilogHDL标准

任务1.2电路设计

任务1.3电路仿真本课件是可编辑的正常PPT课件任务1.1

VerilogHDL标准本课件是可编辑的正常PPT课件VerilogHDL目前有三个标准:IEEE1364-1995、IEEE1364-2001和IEEE1364-2005。这三个标准分别发布于1995年、2001年、2005年,相应的标准可简称为Verilog-1995、Verilog-2001和Verilog-2005。VerilogHDL语言最初是于1983年由GatewayDesignAutomation公司为其模拟器产品开发的硬件建模语言。由于该公司的模拟、仿真器产品广泛使用VerilogHDL,因此该语言作为一种便于使用且实用的语言逐渐为众多设计者所接受。开放Verilog国际组织是促进VerilogHDL发展的国际性组织。1992年OVI决定致力于推广Verilog标准成为IEEE标准并于1995年获得成功(称之为IEEE1364-1995)。本课件是可编辑的正常PPT课件与Verilog-1995相比,Verilog-2001加入了很多有用的特性,这些特性可以提高设计的生产效率、综合能力和验证效率。新特性包括:增加generate语句,简化模块多次实例化或者选择实例化;增强对多维数组的支持;增强文件I/O的操作;增加对task和function重入的支持;增加always@(*);增加新的端口声明方式;等等。与Verilog-2001相比,Verilog-2005增加了Verilog-AMS,支持对集成的模拟和混合信号系统的建模,把寄存器类型改名为变量类型。2009年,IEEE1364-2005和IEEE1800-2005两个部分合并成IEEE1800-2009。IEEE1800-2005和IEEE1800-2009都是SystemVerilog语言标准。SystemVerilog是硬件描述验证语言,是硬件描述语言和硬件验证语言的一个集成。本书所有代码均符合VerilogHDL的IEEE1364-2001标准。关于VerilogHDL标准更多的内容和细节,请读者自行查阅上述VerilogHDL标准。本课件是可编辑的正常PPT课件任务1.2 电

计本课件是可编辑的正常PPT课件HDL,全称硬件描述语言,用来描述电路。采用HDL编写电路描述文件时,可用综合工具生成电路网表文件。电路设计完成后,通常需要查看综合后的电路。本书使用的综合工具软件是Vivado14。该版本支持VerilogHDL的IEEE1364-2001标准。另外,本书部分项目也用到了QuartusⅡ13软件。关于Vivado14和QuartusⅡ13软件的安装和详细使用说明,本书不展开介绍,感兴趣的读者可自行查阅相关资料。在电路设计过程中,可能会结合使用HDL和C语言。HDL与C语言两者有本质区别,如图1-1所示。本课件是可编辑的正常PPT课件C语言是软件语言,编译后生成机器语言程序(机器语言程序是一系列指令),并使CPU执行,并不生成硬件电路,CPU处理软件指令需要取址、译码、执行,代码是串行执行的。HDL是硬件描述语言,综合后生成硬件电路,代码是并行执行的。在电路设计过程中,通常将C语言和HDL语言结合使用,具体表现在:(1)在电路设计中,C语言可以进行先期的算法验证,待算法验证后再使用HDL语言来实现,也就是使用C语言辅助硬件设计。(2) C语言与VerilogHDL硬件描述语言相似,在完全理解了两种语言的语法和功能,并具备了软件思维和硬件思维之后,很容易将C语言的程序转成VerilogHDL语言的程序。本课件是可编辑的正常PPT课件一、设计举例【例1-1】

使用HDL语言描述一个非门。上述代码中,将输出Y描述为输入A取反,可以使用综合工具查看生成的电路。综合的电路如图1-2所示。本课件是可编辑的正常PPT课件【例1-2】

使用HDL语言描述一个D触发器。上述代码中,复位时将q的值赋为0,在clk上升沿将d赋值给q。综合的电路如图1-3所示。本课件是可编辑的正常PPT课件上述电路设计涉及的知识点有:module结构及其相关知识点、assign连续赋值语句、always过程语句。(1) module结构。module和endmodule是VerilogHDL的关键字,用来说明模块。每个模块都可以理解为一颗特定功能的芯片。VerilogHDL程序是由模块构成的,每个模块的内容都嵌在module和endmodule两个语句之间。每个模块可实现特定的功能,且可进行层次嵌套。因此,可将大型的数字电路设计分割成不同的小模块来实现特定的功能,最后通过顶层模块调用子模块来实现整体功能。本课件是可编辑的正常PPT课件(2)端口属性。每个模块需进行端口列表声明,说明输入/输出端口属性,并对模块的功能进行描述。input和output是VerilogHDL的关键字,用来说明模块的端口属性。端口属性分别为input(输入)、output(输出)和inout(输入/输出)。另外,每个模块需进行端口列表声明,说明这些端口的输入、输出属性。(3)信号类型。wire、reg是VerilogHDL语言的关键字,用来说明模块内部信号的属性,包括线网类型、寄存器类型等。在设计过程中,需要注意的是,wire通常用来说明在assign语句中被赋值的变量;reg通常用来说明在initial语句或always语句中被赋值的变量。本课件是可编辑的正常PPT课件(4)注释语句。可以用/*…*/和//…对VerilogHDL程序的任何部分作注释。一个有使用价值的源程序都应当加上必要的注释,以增强程序的可读性和可维护性。(5)书写格式。VerilogHDL程序的书写格式自由,一行可以写几个语句,也可以一个语句分写多行。除了endmodule语句外,VerilogHDL程序中每个语句和数据定义的最后必须有分号。(6) assign连续赋值语句。assign是VerilogHDL语言的关键字,用来说明模块内部信号的连接关系。语句“assignY = ~A;”的功能是:当A = 1时,Y = 0;当A = 0时,Y = 1。assign语句常用于实现简单的组合逻辑电路。(7) always过程语句。always是VerilogHDL语言的关键字,用来说明模块的行为。always语句常用于实现时序逻辑电路和复杂的组合逻辑电路。本课件是可编辑的正常PPT课件二、查看电路图代码设计完成后,可以使用综合工具查看电路图。例如,QuartusⅡ、Vivado、DesignCompiler等都可用于查看综合后的电路图。Vivado设计套件是FPGA厂商Xilinx公司2012年发布的集成设计环境,包括高度集成的设计环境和新一代从系统到IC级的工具。本书使用的集成开发环境是Vivado2014.4。QuartusⅡ是Altera公司的综合性PLD/FPGA开发软件。本书使用的集成开发环境是QuartusⅡ13.1。Vivado和QuartusⅡ均支持原理图、VHDL、VerilogHDL等多种设计输入形式,内嵌自有的综合器以及仿真器,可完成从设计输入到硬件配置的完整设计流程。本课件是可编辑的正常PPT课件下面以Vivado为例来说明查看综合后的电路图的步骤。1.创建新工程(1)打开“Vivado2014.4”设计开发软件,选择“CreateNewProject”,如图1-4所示。(2)在弹出的创建新工程的界面中,点击“Next”按钮,开始创建新工程,如图1-5所示。(3)在“ProjectName”界面中,将工程名称修改为“sw_led_vavido”,并设置好工程存放路径。同时勾选上创建工程子目录的选项。这样整个工程文件都将存放在创建的“sw_led_vavido”子目录中。然后,点击“Next”按钮,如图1-6所示。本课件是可编辑的正常PPT课件(4)在选择工程类型的界面中,选择RTL工程。由于本工程需要创建源文件,因此,无须将“Donotspecifysourcesatthistime”(不指定添加源文件)勾选上。然后,点击“Next”按钮,如图1-7所示。本课件是可编辑的正常PPT课件(5)在创建或添加Verilog源文件界面中,暂时先不新建或添加源文件。点击“Next”按钮,如图1-8所示。(6)在创建或添加约束文件界面中,暂时先不新建或添加约束文件。点击“Next”按钮,如图1-9所示。(7)在器件板卡选型界面中,不选择任何器件,直接点击“Next”按钮。(8)在新工程总结界面中,检查工程创建是否有误。没有问题,则点击“Finish”按钮,完成新工程的创建。本课件是可编辑的正常PPT课件2.添加和编辑源文件(1)点击“ProjectManager”目录下的“AddSources”,如图1-10所示。(2)选择添加源文件。点击“Next”按钮,如图1-11所示。(3)点击“CreateFile…”,创建新文件。在弹出的对话框中输入文件名“sw_led_vivado”,点击“OK”按钮进行新建,如图1-12所示。本课件是可编辑的正常PPT课件(4)在弹出的模块定义对话框中,保持默认,点击“OK”按钮后,在弹出的模块保存对话框中点击“Yes”按钮,完成源文件的创建。(5)双击“sw_led_vivado.v”,在出现的源文件编辑框中完成源文件的编辑,如图1-13所示。本课件是可编辑的正常PPT课件3.查看RTL电路图RTL原理图不是设计开发描述工具,而是综合器输出的一个结果。在FPGA应用开发过程中,可以通过“RTLANALYSIS→Schematic”查看电路图,如图1-14所示。图1-3就是通过这种方法查看D触发器的电路图。

“RTLANALYSIS→Schematic”功能在自顶向下的层级设计中,常用于检查模块端口间的连接是否正确,是一个比较实用的工具。在本书的后续章节中会使用这一工具给出电路原理图,说明模块间的连接关系;同时,在电路图的设计过程中,也常用这个工具来排查错误,尤其是模块间的连接错误。另外,使用其他综合工具也可以查看电路图,如QuartusⅡ、DesignCompiler等。但在其他综合工具中查看的电路图与Vivado中的电路图在外观上不太一致,如例1-2,在QuartusⅡ中查看到的电路图如图1-15所示。本课件是可编辑的正常PPT课件任务1.3 电

仿

真本课件是可编辑的正常PPT课件HDL语言描述的电路功能是否正常,可以使用仿真来验证。本书中的项目使用的仿真工具软件是ModelSim10.0,该版本支持VerilogHDL的IEEE1364-2001标准。本任务详细介绍了Verilog的仿真技术。因为可综合的语法是Verilog语法的一个子集,所以读者要全面了解VerilogHDL的强大功能,就必须详细全面地了解VerilogHDL语法,且为了配合对各种语法进行仿真分析,还需要借助ModelSim软件。ModelSim是一种功能强大的仿真软件,不仅支持向量波形文件的仿真,还支持文本文件的仿真。本课件是可编辑的正常PPT课件一、仿真举例【例1-3】

使用HDL语言对非门进行验证。//显示输出,aa或yy有变化时才打印信息上述代码可以实现对非门的仿真,仿真图形如图1-16所示。本课件是可编辑的正常PPT课件【例1-4】

使用HDL语言对D触发器进行验证。上述代码可以实现对D触发器的仿真,仿真图形如图1-18所示。上述电路仿真涉及的知识点有testbench、模块例化、initial过程语句、延时仿真、多变量处理、循环语句、系统函数、仿真软件force功能等。下面对这些知识点进行说明。本课件是可编辑的正常PPT课件(1) testbench。testbench是一种验证手段。任何设计都会有输入/输出,但是在软环境中没有激励输入,也不会对设计的输出的正确性进行评估,因此testbench就应运而生了。testbench是一种“虚拟平台”,俗称测试台,模拟实际环境的输入激励和输出校验的产生,可以对设计从软件层面上进行分析和校验。测试台mynot_tb的主要功能是为mynot模块提供输入激励信号;测试模块mydff_tb的主要功能是为mydff模块提供输入激励信号。(2)模块例化。测试台调用设计代码称为例化。非门测试的例化语句形式为其中,A和Y为设计代码中的端口信号名,aa和yy为测试代码中相对应的信号名。通过为aa增加激励,可以观察输出yy的响应。这种例化方式称为名称关联例化。本课件是可编辑的正常PPT课件D触发器测试的例化语句形式为mydffUU(clk,rst,d,q);其中,clk、rst、d、q均为测试模块中的信号,而没有出现设计模块中的信号名,这种例化的信号传递是由信号在端口中的位置决定的。这种例化方式称为位置关联例化。应注意测试台中的变量声明与被例化的设计模块中的端口类型说明。例如,测试模块mynot_tb中aa为reg类型,而在设计模块mynot中A为wire类型。测试模块mydff_tb和设计模块mydff,其中的端口类型也是类似的,测试模块mydff_tb中的clk、rst、d等变量均定义成了reg类型,而在设计模块中这些相应的端口均为wire类型。本课件是可编辑的正常PPT课件(3) initial过程语句。initial是VerilogHDL语言的关键字,用来为输入信号添加激励。在测试台mynot_tb中,为aa赋值20次,每次间隔10个时间单位,所赋的值是随机产生的。(4)延时仿真。#N表示的是延时N个时间单位。时间单位通过 'timescale进行说明。在测试台mynot_tb中,repeat(20)#10aa=($random)%2;就是重复20次操作,每次操作的间隔为10个时间单位。(5)多变量处理。当需要为多个变量设置激励时,虽然可以将所有激励写在一个initial语句块或一个always语句块中,但当设计输入信号多且变化情况也多时,则信号激励的产生会不太清晰,甚至会造成逻辑混乱。因此,建议为每个变量单独设置激励,即一个变量的激励设置仅在一个initial语句块或一个always语句块中处理。在测试台mydff_tb中,clk、rst、d都是进行单独设置激励的。本课件是可编辑的正常PPT课件(6)循环语句。forever和repeat用于执行循环,前者表示循环次数无限;后者表示循环次数有限,且在其后括号中说明循环次数。循环语句在仿真中较常用,使用循环语句设置激励比较高效实用。(7)系统函数。调用系统函数时应在函数名前加 $。下面对例中的系统函数的作用进行说明。stop函数用来停止仿真。monitor和display函数用来显示当前变量值。monitor与display的区别是:前者是待显示变量有变化时就会显示该变量的值,而display只显示一次。realtime函数用于显示当前仿真时间。本课件是可编辑的正常PPT课件(8)仿真软件force功能。对于初学者,在ModelSim软件中,除了编写测试台仿真外,也可以直接使用软件中的force按钮产生激励进行仿真。使用force按钮产生激励的优点是不用写测试台程序,可以直接针对设计的输入设置相应的激励,然后直接观察设计的仿真结果。这种方法在一些简单设计中比较直观,减少了初学者编写测试台的干扰,对初学者学习语法和理解设计代码有一定的帮助。但对于熟悉HDL语言的开发者来说,建议在测试台上进行仿真。本课件是可编辑的正常PPT课件二、基于ModelSim的仿真步骤1.创造ModelSim工程(1)点击“开始→程序→ModelSimSE-6410.0c”或双击桌面上的快捷方式,打开ModelSim软件。(2)点击“File→New→Project”,出现如图1-19所示的界面,在“ProjectName”中输入建立的工程名字“MyPrj”,在“ProjectLocation”中输入工程保存的路径为“D:/BOOK_HDL”。注意:ModelSim不能为一个工程自动建立一个目录,创建者应自己在ProjectLocation中输入路径来为工程建立目录,使用自己创建的目录;在“DefaultLibraryName”中设置设计编译后存放的目标库,使用默认值。本课件是可编辑的正常PPT课件(3)编译设计文件后,在Workspace窗口的Library中会出现work库。完成各项设置后,点击“OK”按钮。2.添加工程文件在如图1-20所示的界面中,可以点击不同的图标来为工程添加不同的项目。点击“CreateNewFile”可以为工程添加新建的文件,点击“AddExistingFile”为工程添加已经存在的文件,点击“CreateSimulation”为工程添加仿真,点击“CreateNewFolder”可以为工程添加新的目录。这里我们点击“CreateNewFile”。(1)点击“CreateNewFile”,出现如图1-21所示的界面。本课件是可编辑的正常PPT课件(2)在“FileName”框中输入“MyFile”。在“Addfileastype”下拉框中选择“Verilog”,如图1-21所示,点击“OK”按钮。(3)打开“MyFile.v”文件,录入设计代码和测试代码,代码文件如下所示。【例1-5】

计数器的设计代码和测试代码。上述设计代码和测试代码均写在一个文件中。实际开发过程中,也可以将设计代码和测试代码分别写入两个不同名称的文件。本课件是可编辑的正常PPT课件录入代码后,如图1-22所示。本课件是可编辑的正常PPT课件3.编译工程通过图1-23可以看出,在Workspace窗口中的“Project”选项卡里,“MyFile.v”文件状态栏有问号,这表示该文件未曾编译或者编译后又进行了修改。对文件的编译过程如下:(1)选择“Compile→CompileSelected”或者“Compile→CompileAll”,如图1-23所示。(2)在命令窗口中将出现“#CompileofMyfile.vwassuccessful.”,且在状态栏后有一对号,表示编译成功,如图1-24所示。如果编译出错,则可以双击错误弹出错误的提示信息,然后根据提示进行排错。排错后再次编译,如果编译还出错,就继续排错,直到编译成功为止。本课件是可编辑的正常PPT课件4.仿真(1)选择“Library”标签,出现如图1-25所示的界面。(2)展开“work”库,并选中其中的“counter_tb”,即顶层测试模块,也是所要仿真的对象。选中后单击右键,选择“Simulationwithoutoptimization”后,弹出如图1-26所示的界面,在该界面中可以看到sim标签页和Wave标签页,表明仿真设置成功。本课件是可编辑的正常PPT课件(3)为了观察波形窗口,需要为该窗口添加需要观察的对象,首先,在主窗口勾选“View→debugWindows→Objects”,打开信号列表窗口如图1-27所示,在该窗口中点击“Add→ToWave→SignalsinRegion”,在波形窗口中就可以看到clk、rst和cnt信号。(4)在主窗口中输入“run1μs”后回车,表示运行仿真1μs,仿真时CPU的利用率一直为100%,如果仿真较慢,则还可以观察状态栏里的当前仿真时间。(5)仿真完成后,点击Wave标签页,可以看到仿真波形。本课件是可编辑的正常PPT课件5.功能仿真结果分析首先,给Wave窗口增加一个cnt,并将其中一个cnt设置成无符号十进制,即“unsigned”,另一个cnt设置成模拟信号输出,即“Analog”,设置界面如图1-28所示。本课件是可编辑的正常PPT课件按图1-28所示,将“Radix”设置为“unsigned”,将“Format”设置为“Analog”。设置完成后,仿真波形如图1-29所示。根据仿真结果可知,该设计实现了一个0~15的计数器。如果外加DAC器件将数字量变成模拟量,该设计则很容易产生一个锯齿波。本课件是可编辑的正常PPT课件三、结构化过程语句InitialInitial语句通常用于仿真过程中对输入信号执行一次添加激励的操作。所有在initial语句内的语句构成了一个initial块。initial块从仿真0时刻开始执行,在整个仿真过程中只执行一次。如果一个模块中包括了若干个initial块,则这些initial块从仿真0时刻开始并发执行,且每个initial块的执行是各自独立的。initial块的使用类似于always块(always语句将在“任务4.1”中进行详细描述),块内使用的语句必须是行为语句,应用于always块内的语句均可应用于initial块。在一个模块内,可同时包括若干个initial块和若干个always块,所有这些块均从仿真0时刻开始并发执行,且每个块的执行是各自独立的。如果在initial块内包含了多条行为语句,则需要将这些语句组成一组,使用关键字begin和end(或者fork和join)将它们组合为一个块语句;如果块内只有一条语句,则无须使用关键字begin和end(或者fork和join)。这一点类似于C语言中的复合语句{}。本课件是可编辑的正常PPT课件initial语句的格式如下:由于initial块语句在整个仿真期间只能执行一次,因此,它一般用于初始化、信号监视、生成仿真波形等。下面举例说明initial语句的使用。【例1-6】initial块语句举例。本课件是可编辑的正常PPT课件程序说明:(1)程序中各变量的波形图如图1-30所示。从图1-30中的仿真波形可以看出,多个initial块都是从仿真0时刻开始并发执行的。(2)程序中,一个initial语句仅对应着一个变量的赋值,使程序简洁易懂。(3)块内的语句按顺序执行,即只有上面一条语句执行完后,下面的语句才能执行。(4)每条语句的延时时间是相对于前一条语句的仿真时间而言的。(5)直到最后一条语句执行完,程序流程控制才跳出该initial语句块。本课件是可编辑的正常PPT课件(6)在仿真过程中,如果某条语句前面存在延时,那么对这条语句的仿真将会停顿下来,经过指定的延时时间之后再继续执行(可结合代码和波形图进行理解)。(7)在程序的for语句中加入延时,是为了看清楚初始化过程。(8)在VerilogHDL中,可以给每个顺序块和并行块取一个名字,只需将名字加在关键词begin或fork后面即可。这样做的原因有以下几点:①

可以在块内定义局部变量,即只在块内使用的变量,本例为变量t。②

可以允许块被其他语句调用,如被disable语句调用。③

在Verilog语言里,所有的变量都是静态的,即所有的变量都只有一个唯一的存储地址,因此,进入或跳出块并不影响存储在变量内的值。基于以上原因,块名就提供了一个可在任何仿真时刻确认变量值的方法。本课件是可编辑的正常PPT课件(9)本例中,可使用fork…join替换begin…end,读者可以学习体会两者的区别。fork…join语句块中,所有语句均是并行的,每条语句的执行时刻仅与该语句前面的延时相关,与其他语句的延时无关。(10)从本例可以看出,initial语句的用途之一,是初始化各变量;initial语句的另一用途,是用initial语句来生成激励波形作为电路的测试仿真信号,如图1-30中的x即可用作电路的激励信号。initial块常用于测试文件的编写,用来产生仿真测试信号和设置信号记录等仿真环境。四、延时仿真设计电路时,描述的电路都是无延时的。而在实际的电路中,任何一个逻辑门都具有延时,Verilog允许用户通过延时语句来说明逻辑电路中的延时。通常,在测试激励块中都需要使用延时,下面将对延时作进一步说明。信号在电路中传输会有传播延时,如线延时、器件延时等。所谓延时就是对延时特性的HDL描述,举例如下:本课件是可编辑的正常PPT课件assign#2B=A;表示B信号在2个时间单位后得到A信号的值,如图1-31所示。在VerilogHDL中,所有延时都必须根据时间单位进行定义,定义的方法是在module前添加如下语句:`timescale1ns/100ps其中,`timescale是VerilogHDL提供的编译预处理命令,1 ns表示时间单位是1 ns,100 ps表示时间精度是100ps。根据该命令,编译工具才可以认知 #2为2 ns。在VerilogHDL的IEEE标准中,没有规定时间单位的缺省值,由各仿真工具确定。因此,在编写代码时必须确定时间单位。本课件是可编辑的正常PPT课件在Verilog中,时序控制起着非常重要的作用,它使得设计者可以指定赋值发生的时刻,进而控制仿真时间的推进过程。基于延时的时序控制出现在表达式中,它指定了语句开始执行到执行完成之间的时间间隔。延时值可以是数字、标识符或表达式,但需要在延时值加上关键字 #。`timescale命令用来说明跟在该命令后的模块的时间单位和时间精度。使用`timescale命令可以在同一个设计里包含采用了不同的时间单位的模块。例如,一个设计中包含了两个模块,其中一个模块的时间延时单位为ns,另一个模块的时间延时单位为ps,EDA工具仍然可以对这个设计进行仿真测试。`timescale命令的格式如下:`timescale<时间单位>/<时间精度>本课件是可编辑的正常PPT课件在这条命令中,时间单位参量用来定义模块中仿真时间和延时时间的基准单位。时间精度参量用来声明该模块的仿真时间的精确程度,该参量被用来对延时时间值进行取整操作(仿真前),因此,该参量又被称为取整精度。如果在同一个程序设计里,存在多个`timescale命令,则用最小的时间精度值来决定仿真的时间单位。另外,时间精度要和时间单位一样精确,时间精度值不能大于时间单位值。在 `timescale命令中,用于说明时间单位和时间精度参量值的数字必须是整数,其有效数字为1、10、100,单位为秒(s)、毫秒(ms)、微秒(μs)、纳秒(ns)、皮秒(ps)等。这几种单位的意义见表1-1的说明。本课件是可编辑的正常PPT课件下面举例说明`timescale命令的用法。【例1-7】`timescale命令的用法举例。程序运行结果如图1-32所示。程序说明:(1) `timescale命令定义了模块test的时间单位为10 ns、时间精度为1 ns。在这个命令之后,模块中所有的时间值都是10 ns的倍数,并且可表达为带一位小数的实型数,这是因为 `timescale命令定义的时间精度为时间单位的1/10。(2)参数d = 1.37,根据时间精度,d的值应为1.4(四舍五入),再根据时间单位,d所代表的时间为14ns(即1.4 × 10 ns)。(3) #dset = 0;中,d为延时值,#d表示延时d秒,整个句子表达的意思是延时d秒后再将set赋值为0。延时值可以是数字、标识符或表达式,表示延时时需要在延时值前加上关键字 #。(4)本例的仿真过程为:在仿真时刻为14 ns时,寄存器set被赋值0;在仿真时刻为28ns时,寄存器set被赋值1。本课件是可编辑的正常PPT课件五、仿真常用系统函数和任务VerilogHDL语言中有以下系统函数和任务:$bitstoreal、$rtoi、$display、$setup、$finish、$skew、$hold、$setuphold、$itor、$strobe、$period、$time、$printtimescale、$timefoemat、$realtime、$width、$realtobits、$write、$recovery等。VerilogHDL语言中的每个系统函数和任务前面都应用一个标识符 $ 来加以确认。这些系统函数和任务提供了非常强大的功能,有兴趣的读者可以参阅相关书籍。下面仅对一些常用的系统函数和任务进行介绍。1.系统任务$display、$write和$strobe格式:本课件是可编辑的正常PPT课件这三个函数和系统任务的作用是用来输出信息,即将参数p2~pn按参数p1给定的格式输出。参数p1通常称为“格式控制”,参数p2~pn通常称为“输出表列”。这三个任务的作用基本相同。$display在输出后自动地进行换行,$write则不是这样,如果想在一行里输出多个信息,可以使用$write;$strobe是在同一仿真时刻的其他语句执行完成之后才执行。在$display、$write和$strobe中,其输出格式控制是用双引号括起来的字符串,它包括两种信息:格式说明和普通字符。(1)格式说明由“%”和格式字符组成,它的作用是将输出的数据转换成指定的格式输出。格式说明总是由“%”字符开始的,对于不同类型的数据用不同的格式输出。表1-2中给出了常用的几种输出格式。本课件是可编辑的正常PPT课件(2)普通字符即需要原样输出的字符。其中一些特殊的字符可以通过表1-3中的转换序列来输出。表1-3中的字符形式用于格式字符串参数中,用来显示特殊的字符。在 $display和 $write的参数列表中,其“输出表列”是需要输出的一些数据,可以是表达式。下面举几个示例进行说明。本课件是可编辑的正常PPT课件【例1-8】$display应用举例。

其输出结果如图1-33所示。本课件是可编辑的正常PPT课件程序说明:(1)使用 $display时,输出列表中数据的显示宽度是自动按照输出格式进行调整的。因此,在显示输出数据并经过格式转换以后,总是用表达式的最大可能值所占的位数来显示表达式的当前值。在用十进制数格式输出时,输出结果前面的0值用空格来代替。对于其他进制,输出结果前面的0仍然显示出来。对于一个位宽为7位的值,如按照十六进制数输出,则输出结果占2个字符的位置,如按照十进制数输出,则输出结果占3个字符的位置。这是因为这个表达式的最大可能值为7F(十六进制)或127(十进制)。因此,可以通过在%和表示进制的字符中间插入一个0,自动调整显示输出数据宽度的方式,使输出时总是用最少的位数来显示表达式的当前值。本课件是可编辑的正常PPT课件例如:$display("hex:%0h,decimal:%0d",a,a);(2)如果输出列表中表达式的值包含有不确定的值或高阻值时,其结果输出应遵循一定的规则。下面分别针对十进制、八进制/十六进制、二进制进行说明。①

在输出格式为十进制的情况下:如果表达式值的所有位均为不定值,则输出结果为小写的x。如果表达式值的所有位均为高阻值,则输出结果为小写的z。如果表达式值的部分位为不定值,则输出结果为大写的X。如果表达式值的部分位为高阻值,则输出结果为大写的Z。本课件是可编辑的正常PPT课件②

在输出格式为十六进制和八进制的情况下:每4位二进制数为一组,代表一位十六进制数;每3位二进制数为一组,代表一位八进制数。如果表达式值相对应的一位八进制(十六进制)数的所有位均为不定值,则该位八进制(十六进制)数的输出结果为小写的x。如果表达式值相对应的一位八进制(十六进制)数的所有位均为高阻值,则该位八进制(十六进制)数的输出结果为小写的z。如果表达式值相对应的一位八进制(十六进制)数的部分位为不定值,则该位八进制(十六进制)数输出结果为大写的X。如果表达式值相对应的一位八进制(十六进制)数的部分位为高阻值,则该位八进制(十六进制)数输出结果为大写的Z。本课件是可编辑的正常PPT课件③

对于二进制输出格式,表达式值的每一位的输出结果为0、1、x、z。选通显示($strobe)与 $display作用大同小异。如果许多其他语句与 $display任务在同一时刻执行,那么,这些语句与 $display任务的执行顺序是不确定的。如果使用 $strobe,该语句总是在同一时刻的其他语句执行完成之后才执行。因此,它可以确保所有在同一时刻赋值的其他语句执行完成后,才显示数据。【例1-9】$strobe应用举例。本课件是可编辑的正常PPT课件输出结果如下:#$display:val=0#$strobe:val=1程序说明:(1)由于val<=1;是非阻塞赋值,要在此仿真时刻最后才完成赋值,因此,非阻塞语句的赋值在所有的$display命令执行以后才更新数值;由于$display在val=0;语句之后,所以显示的val值,为此刻的值0。(2) $strobe语句总是在同一时刻的其他语句执行完成之后才执行,它显示val非阻塞赋值完成后的值1。因此,建议读者用$strobe系统任务来显示用非阻塞赋值的变量的值。本课件是可编辑的正常PPT课件2.系统任务 $monitor格式:任务 $monitor提供了监控和输出参数列表中的表达式或变量值的功能,其参数列表中输出控制格式字符串和输出表列的规则和 $display的一样。当启动一个带有一个或多个参数的$monitor任务时,仿真器则建立一个处理机制,使得每当参数列表中的变量或表达式的值发生变化时,整个参数列表中的变量或表达式的值都将输出显示。如果同一时刻,有多于一个的参数值发生变化,在该时刻也只输出显示一次。本课件是可编辑的正常PPT课件$monitoron和 $monitoroff任务是通过打开和关闭监控标志来控制监控任务 $monitor的启动和停止。其中,$monitoroff任务用于关闭监控标志,停止监控任务 $monitor;$monitoron用于打开监控标志,启动监控任务 $monitor。通常在调用 $monitoron启动 $monitor时,不管 $monitor参数列表中的值是否发生变化,总是立刻输出显示当前时刻参数列表中的值,这些值可用于在监控的初始时刻设定初始比较值。在缺省情况下,控制标志在仿真的起始时刻就已经打开了。在多模块调试的情况下,许多模块中都调用了 $monitor,因为任何时刻只能有一个 $monitor起作用,因此,需配合 $monitoron与 $monitoroff使用,把需要监视的模块用 $monitoron打开,在监视完毕后及时用 $monitoroff关闭,以便把 $monitor让给其他模块使用。$monitor与 $display的不同处还在于 $monitor往往在initial块中被调用,只要不调用 $monitoroff,$monitor便可不间断地对所设定的信号进行监视。本课件是可编辑的正常PPT课件3.时间度量系统函数$time在VerilogHDL中有两种类型的时间系统函数:$time和 $realtime。用这两个时间系统函数可以得到当前的仿真时刻。系统函数 $time可以返回一个用64比特整数表示的当前仿真时刻值,该时刻以模块的仿真时间尺度为基准。$realtime和 $time的作用一样,只是 $realtime返回的时间数字是一个实型数,该数字也是以仿真时间尺度为基准的。下面举例说明。【例1-10】$monitor和$time应用举例。本课件是可编辑的正常PPT课件输出结果如下:本课件是可编辑的正常PPT课件程序说明:(1)在这个例子中,模块monit设置为在时刻为14 ns时设置寄存器data为0,在时刻为28 ns时设置寄存器data为1,在42ns时设置寄存器data为0,在56 ns时设置寄存器data为1。但是,由 $time记录的data变化时刻却和预想的不一样。(2) $time显示时刻受时间尺度比例的影响。在本例中,时间单位是10 ns,因为 $time输出的时刻是时间单位的倍数,即14 ns、28 ns、42 ns和56 ns输出为1.4、2.8、4.2和5.6。又因为 $time是输出整数,所以在将经过尺度比例变换的数字输出时,需要先进行取整。在本例中,1.4、2.8、4.2和5.6经取整后为1、3、4和6。注意:时间精度并不影响数字的取整。(3)若将例子中 $monitor($time,"data=",data); 改为$monitor($realtime,"data=",data);,则输出结果如下:本课件是可编辑的正常PPT课件从输出结果可以看出,$realtime将仿真时刻经过尺度变换以后输出,不需进行取整操作。所以,$realtime返回的时刻是实型数。(4)可以使用$monitor($time,"%0tdata=%0d",$time,data); 来去掉输出中的空格,也可以在格式符中使用具体的数值来规定输出占据的位宽。若读者想了解更多格式符的使用方法,可自行查阅相关资料。4.系统任务$finish和$stop1) $finish格式:系统任务$finish的作用是退出仿真器,返回主操作系统,也就是结束仿真过程。任务$finish可以带参数,根据参数的值输出不同的特征信息。如果不带参数,则默认$finish的参数值为1。本课件是可编辑的正常PPT课件下面给出了对于不同的参数值,系统输出的特征信息:0表示不输出任何信息;1表示输出当前仿真时刻和位置;2表示输出当前仿真时刻、位置和在仿真过程中所用memory及CPU时间的统计。2) $stop格式:$stop任务的作用是把EDA仿真器设置成暂停模式,在仿真环境下给出一个交互式的命令提示符,将控制权交给用户。这个任务可以带有参数表达式,根据参数值(0,1或2)的不同,输出不同的信息,参数值越大,输出的信息越多。本课件是可编辑的正常PPT课件5.系统任务$readmemb和$readmemh在VerilogHDL程序中有两个系统任务$readmemb和$readmemh,用来从文件中读取数据到存储器中。这两个系统任务可以在仿真的任何时刻执行使用,其共有以下六种使用格式:(1) $readmemb("<数据文件名>",<存储器名>);(2) $readmemb("<数据文件名>",<存储器名>,<起始地址>);(3) $readmemb("<数据文件名>",<存储器名>,<起始地址>,<结束地址>);(4) $readmemh("<数据文件名>",<存储器名>);(5) $readmemh("<数据文件名>",<存储器名>,<起始地址>);(6) $readmemh("<数据文件名>",<存储器名>,<起始地址>,<结束地址>);本课件是可编辑的正常PPT课件规则如下:(1)第一个变量是一个ASCII文件的名字,这个文件可以只包含空白位置(空格、换行、制表格tab和form-feeds)、Verilog注释(//形式的和/*…*/形式的都允许)、hex地址值以及二进制或十六进制数字。数字中不能包含位宽说明和格式说明,对于$readmemb系统任务,每个数字必须是二进制数字;对于$readmemh系统任务,每个数字必须是十六进制数字。数据值必须和存储器数组的宽度相同,而且用空白分隔。(2)第二个变量是存储器数组的名字。(3)当数据文件被读取时,每一个被读取的数字都被存放到地址连续的存储器单元中。存储器单元的存放地址范围由系统任务声明语句中的起始地址和结束地址来说明,每个数据的存放地址在数据文件中进行说明。本课件是可编辑的正常PPT课件(4)地址值是带前缀@的十六进制且允许大写和小写的数字。在字符“@”和数字之间不允许存在空白位置。可以在数据文件里出现多个地址。当系统任务遇到一个地址说明时,系统任务将该地址后的数据存放到存储器中相应的地址单元中。下面举例说明系统任务$readmemb和$readmemh的应用。【例1-11】

系统任务$readmemb和$readmemh应用举例。程序使用的文件“Mem.txt”如图1-34所示。程序运行结果如图1-35所示。本课件是可编辑的正常PPT课件关于系统任务 $readmemb和 $readmemh的进一步说明:(1)如果系统任务声明语句和数据文件中都没有进行地址说明,则缺省的存放起始地址为该存储器定义语句中的起始地址。数据文件里的数据被连续存放在该存储器中,直到该存储器单元存满或数据文件里的数据存完为止。(2)如果系统任务中说明了存放的起始地址,没有说明存放的结束地址,则数据从起始地址开始存放,存放到该存储器定义语句中的结束地址为止。(3)如果在系统任务声明语句中,起始地址和结束地址都进行了说明,则数据文件里的数据按该起始地址开始存放到存储器单元中,直到该结束地址,而不考虑该存储器的定义语句中的起始地址和结束地址。(4)如果地址信息在系统任务和数据文件里都进行了说明,那么数据文件里的地址必须在系统任务中地址参数声明的范围之内。否则将提示错误信息,并且装载数据到存储器中的操作被中断。(5)如果数据文件里的数据个数和系统任务中起始地址及结束地址暗示的数据个数不相同,会提示错误信息。本课件是可编辑的正常PPT课件6.系统任务 $fopen和 $fclose$fopen是打开一个文件进行写操作的系统函数,用 $fdisplay、$fmonitor等系统任务将文本写入到文件。$fclose是关闭一个文件的系统任务。格式:规则:(1)当调用 $fopen函数时,它返回一个与文件关联的32位的文件句柄或者是0(文件不能打开时)。若返回的是文件句柄,则该文件句柄只有1位被置成1,并且按照文件被打开的顺序,依次将位1,位2,位3,…,位31置位。(2)多通道描述符可以是一个文件句柄或者多个文件句柄按位的组合。多通道描述符为32位,可以认为是32个标志。每个标志表示一个独立的文件通道:位0和标准输出关联;位1和第一个打开的文件关联;位2和第二个打开的文件关联,以此类推。(3)一次可以同时打开32个文件,并且可以有选择地同时写多个文件。(4)当一个文件的输出系统任务(如 $fdisplay)被调用时,第一个变量是一个多通道描述符,它表示在哪里写文本,文本被写在多通道描述符的标志被置位的文件中。系统任务 $fdisplay、$fmonitor、$fwrite、$fstrobe都用于写文件。本课件是可编辑的正常PPT课件下面举例说明。【例1-12】

文件读写应用举例。程序说明:(1)程序运行后,在ModelSim命令窗口出现“#Startingsimulation...”信息,在文件“messages”和“result”中写入如图1-36所示的信息。本课件是可编辑的正常PPT课件(2)本例中,desc1的值为32'h0000_0002(位1被置成1),desc2的值为32'h0000_0004(位2被置成1)。AllFiles=desc1|desc2|1;执行后,AllFiles的值为32'h0000_0007(最低3位均被置成1),也就是说AllFiles包含了3个文件;AllFiles=desc1|desc2;执行后,AllFiles的值为32'h0000_0006(位2和位3被置成1),也就是说AllFiles包含了2个文件。(3)多通道描述符的优点在于可以有选择地同时写多个文件。多通道描述符可以是一个文件句柄或者多个文件句柄按位的组合,Verilog会把输出写到与多通道描述符中值为1的位相关联的所有文件中。例如,“#Startingsimulation...”信息被同时写入了3个文件(包括标准输出),“Importantinformation...”信息被同时写入了2个文件。本课件是可编辑的正常PPT课件7.系统任务综合应用举例下面再通过一个例子来说明系统函数的使用。该例子是使用ModelSim读出正弦波数据文件中的数据,并生成正弦波。在实际的应用中,可能需要较大的数据量,使用传统的方法在测试文件中指定输入数据不太现实。通常,用其他软件(如C、MATLAB等软件)生成所需的数据,并保存在 *.dat文件中,然后在ModelSim中调用该文本文件,将文本中的数据读出使用。同样的,输出数据量也较大时,用传统的方法去看输出波形也是不可靠的,因此需要把结果也输出到文本中,与行为模型所产生的标准输出向量作对比,这样就可以比较简单且准确地指示结果是否正确。首先,使用C语言创建“sin.dat”文件,一共100个正弦波数据,涵盖了一个完整的周期,均以十六进制格式存放,其内容如图1-37所示。本课件是可编辑的正常PPT课件【例1-13】

生成正弦波数据的C语言程序所示。该程序将正弦波数据通过取正弦后加1,然后再乘以100,这样就使正弦波数据都位于0~200之间。然后,通过例1-14来说明如何使用ModelSim读该文件数据并输出这些数据,形成正弦波。本课件是可编辑的正常PPT课件【例1-14】

使用ModelSim读写文件生成正弦波。程序说明:(1)仿真波形如图1-38所示。本课件是可编辑的正常PPT课件(2)命令窗口显示结果。由于命令窗口显示的仿真结果较长,所以仅摘抄一部分,供读者分析程序使用,如图1-39所示。(3)本程序中使用了 $display、$monitor、$fopen、$fclose、$fdisplayh、$readmemh、$finish等系统任务,关于这些任务的用法与含义,可结合本书前面章节的内容理解或自行查阅相关书籍学习。(4)实际开发中,可以将任意波形数据存放在文件中,然后通过读取文件的方式生成任意波形,也可以通过这种方式制作信号发生器。本节对一些常用的系统函数和任务逐一进行了介绍,在此基础上,读者可以在ModelSim软件中编写功能强大的测试激励块,更好地使用ModelSim软件的功能。通过本节的学习,我们可以发现ModelSim不仅好用,而且易用。本课件是可编辑的正常PPT课件任务2.1连续赋值语句任务2.2运算符类型任务2.3基本语法及其学习建议任务2.1连续赋值语句以关键词assign开始的语句为连续赋值语句。连续赋值语句是Verilog数据流建模的基本语句,用于对线网进行赋值。assign语句对应的电路通常都是组合逻辑电路。下面介绍3个电路设计案例:多路选择器、奇偶校验器、加法器。【例2-1】

二选一多路选择器电路设计。

【例2-2】

二选一多路选择器电路仿真。使用QuartusⅡ软件可以对设计进行综合,综合出来的电路图如图2-1所示。由图2-1可以看出,该设计实现的是一个二选一选择电路。奇/偶校验(ParityCheck)是数据传送时采用的一种校正数据错误的方式,根据被传输的一组二进制代码的数位中“1”的个数是奇数或偶数来进行校验。【例2-3】

奇校验电路设计。

【例2-4】

奇校验电路仿真。仿真输出结果如图2-2所示。在仿真结果中可直接观察输入数据以及其中1的个数,并跟输出的1的个数进行对比。【例2-5】

使用数据流建模实现一位半加器。解题指引:半加器实现的是不带进位的两个数的相加,若半加器的输入为ain和bin,输出为sum和co。其中,sum为和,co为进位。半加器的真值表如表2-1所示。Verilog实现代码如下:上面例2-3、例2-4和例2-5都是数据流建模,且都使用了assign语句,该语句通常使用连续赋值语句对变量进行赋值,赋值语句通常会涉及大量的运算符。上述电路设计和仿真涉及的知识点有:assign连续赋值语句、运算符、系统函数、循环语句、延时等。下面对这些知识点进行说明。(1) assign连续赋值语句。assign是VerilogHDL语言的关键字,是数据流建模的典型特征。连续赋值语句的基本元素是表达式、运算符和操作数。连续赋值语句的功能是计算右侧表达式的值,然后赋给左边变量。表达式由运算符和操作数构成,根据运算符界定的功能对操作数进行运算后,得出结果。数据流的强大建模能力体现在多种运算符类型上。连续赋值语句总是处于激活状态,只要任意一个操作数发生变化,表达式就会立即被重新计算,并且将结果赋给等号左边的线网型变量。assign{co,sum}=ain+bin;是一条连续赋值语句,它将ain和bin的和存放在{co,sum}中。该语句中,“{}”为位拼接符,其完成的功能是将co和sum拼接成一个两位数。连续赋值语句的左边必须是一个标量或向量线网,或者是标量或向量线网的拼接,而不能是任何形式的寄存器。例如,下面的形式是非法的:操作数可以是线网型标量或向量,也可以是寄存器型标量或向量。(2)运算符。语句assigny=s?b:a;使用了条件运算符,其功能是:当s = 1时,y = b;当s = 0时,y = a。语句{a,b,s}={a,b,s}+1;使用了算术运算符、拼接运算符,{a,b,s}的功能是将三个1位数a、b、s拼接成一个三位数;使用的算术运算符是“+”。assign{co,sum}=ain+bin; 使用了算术运算符、拼接运算符。(3)系统函数。monitor和time都是VerilogHDL语言的系统函数,monitor监控变量值,当要显示的变量值发生变化时就会显示;time用于显示当前仿真时刻。(4)循环语句和仿真延时。forever是VerilogHDL语言的关键字,用来一直产生信号。forever#5d_in=d_in+1;语句的含义是每5个时间单位,变量值加1。任务2.2 运

型VerilogHDL语言提供了许多类型的运算符,分别是算术、关系、逻辑、按位、缩减、条件、移位和位拼接运算符。表2-2按运算符类型列出了常用的运算符。由表2-2可知,VerilogHDL语言中的运算符所带的操作数是不同的。只带1个操作数的运算符称为单目运算符,此时操作数需放在运算符的右边;带2个操作数的运算符称为双目运算符,操作数需放在运算符的两边;带3个操作的运算符称为三目运算符,这3个操作数用三目运算符分隔开,如表2.2中的条件运算符就是三目运算符。表达式中的操作数可以是以下类型中的一种。(1)常数。(2)参数。(3)线网。(4)寄存器。(5)位选择。(6)部分选择。(7)存储器单元。(8)函数调用。下面对表2-2中的运算符分别进行介绍。一、算术运算符算术运算符包括加(+)、减(-)、乘(×)、除( / )、取模(%)、乘方(**)。依据运算的不同,算术运算符分别对应着加法器、减法器、乘法器、除法器、取余电路。电路设计中,加法器通常由基本的逻辑门实现,乘法器则由加法器来实现。算术运算符的具体示例说明如表2-3所示。使用算术运算符时需注意以下几点:(1)加(+)、减(-)、乘(×)、除( / )、取模(%)、乘方(**)均为双目运算符,要求运算符两侧均有操作数。(2)在进行整数除法运算时,结果值要略去小数部分,只取整数部分。(3)乘方运算符要求幂是一个常量,不能为变量。(4)模运算符又称为求余运算符,要求%两侧均为整型数据。(5)进行取模运算时,结果值的符号位采用模运算式里第一个操作数的符号位。表2-4中列举了一些例子。二、关系运算符关系运算符包括大于(>)、小于(<)、大于等于(>=)、小于等于(<=)、等于(==)、不等于(!==)。关系运算符对应的实际电路是比较器。关系运算符的具体示例说明如表2-5所示。在进行关系运算时,如果声明的关系是假的(false),则返回值是0;如果声明的关系是真的(true),则返回值是1。关系运算符中大于、小于、大于等于、小于等于有着相同的优先级别,等于、不等于有着相同的优先级别,前者的优先级别大于后者的优先级别。关系运算符的优先级别低于算术运算符的优先级别。例如:从上面的例子可以看出这两种不同运算符的优先级别。当表达式size - (1 < a)进行运算时,关系表达式先运算,然后返回结果值0或1被size减去;而当表达式size - 1 < a进行运算时,size先减去1,然后再同a相比。三、按位运算符按位运算符包括取反( ~ )、按位与( & )、按位或( | )、按位异或( ^ )、按位同或(~^ 和 ^~)。按位运算符对应的电路是基本的逻辑门,如&对应与门,| 对应或门,~对应非门,^对应异或门。按位运算符的具体示例说明如表2-6所示。位运算符中除了~是单目运算符以外,其余均为双目运算符。位运算符中的双目运算符要求对两个操作数的相应位进行运算操作。表2-7所示为按位操作的逻辑规则。对按位运算符的说明如下:(1)两个长度不同的数据进行位运算时,系统会自动地将两者按右端对齐。位数少的操作数会在相应的高位用0填满,以使两个操作数按位进行操作。(2)按位运算符与逻辑运算符虽然符号相近,但两者完全不同。逻辑运算符执行逻辑操作,运算的结果是一个逻辑值0或1;而按位运算符则产生一个与较长位宽操作数等宽的数值,该数值的每一位都是两个操作数按位运算的结果。四、缩减运算符缩减运算符包括缩减与(&)、缩减与非(~&)、缩减或( | )、缩减或非(~ | )、缩减异或( ^ )、缩减同或(~^和^~)。缩减运算符对应的电路是基本的逻辑门,如&对应与门,| 对应或门,~ 对应非门,^对应异或门。缩减运算符的具体示例说明如表2-8所示。位运算符中除了 ~ 是单目运算符以外,其余均为双目运算符;而缩减运算符是单目运算符,也有与、或、非运算。其与、或、非运算规则类似于位运算符的与、或、非运算规则,但运算过程不同。位运算是对操作数的相应位进行与或非运算,操作数是几位数,则运算结果也是几位数;而缩减运算则不同,缩减运算是对单个操作数进行与或非递推运算,最后的运算结果是一位的二进制数。缩减运算的具体运算过程为:第一步,将操作数的第一位与第二位进行与或非运算;第二步,将运算结果与第三位进行或与非运算;依次类推,直至最后一位。例如:上述代码对应的电路是一个4输入的与门。由于逻辑运算符、按位运算符、缩减运算符都使用相同的符号表示,因此容易混淆。区分这些运算符的重点在于分清操作数的数目和运算的规则。五、逻辑运算符逻辑运算符包括逻辑与(&&)、逻辑或(| |)、逻辑非(!)。逻辑运算符对应的实际电路是基本的逻辑门。如果操作数是一位的,则逻辑运算符直接对应着逻辑门,与按位逻辑运算符的功能相同;如果操作数是多位的,则对应的电路就稍微复杂一些。逻辑运算符的具体示例说明如表2-9所示。“&&”和“| |”是双目运算符,它们要求有两个操作数,如(a>b)&&(b>c),(a<b)||(b<c)。“!”是单目运算符,只要求一个操作数,如!(a>b)。表2-10为逻辑运算的真值表,它表示当a和b的值为不同的组合时,各种逻辑运算所得到的值。逻辑运算符中“&&”和“||”的优先级别低于关系运算符,“!”高于算术运算符。例如:六、条件运算符条件运算符( ?: )带有三个操作数:条件表达式 ? 、真表达式 : 、假表达式 ; 。条件运算符与case语句、if语句对应的电路都是多路选择器。下面以case语句为例进行说明,如表2-11所示。执行过程为:首先计算条件表达式,如果为真,则计算真表达式的值;如果为假,则计算假表达式的值。条件运算符可以嵌套使用,每个真表达式或假表达式也可以是一个条件运算符表达式。条件表达式的作用相当于控制开关。【例2-6】

使用条件运算符来实现一个四选一多路选择器。程序说明如下:(1) assignout=(sel[1])?(sel[0]?in1:in2):(sel[0]?in3:in4); 在真表达式和假表达式中均嵌套了一个条件运算符表达式。程序的运算过程如下:首先判断sel[1]是否为真,若为真则计算(sel[0]?in1:in2),否则计算(sel[0]?in3:in4);然后按照同样的规则计算这两个条件运算符表达式。(2)本代码实现了一个四选一多路选择器,输出由条件sel决定。当sel为2'b11时,选择in1;当sel为2'b10时,选择in3;当sel为2'b01时,选择in2;当sel为2'b00时,选择in4。(3)这段代码可以很容易地使用case语句或者if语句来实现。例如:上面的代码使用case语句来实现与例2-16完全相同的功能。七、移位运算符移位运算符包括左移位运算符(<<)和右移位运算符(>>)。移位运算符对应的实际电路是线的对应连接关系,不消耗逻辑资源。移位运算符的具体示例说明如表2-12所示。移位运算符的使用方法如下:a>>n或a<<na代表要进行移位的操作数,n代表要移几位。这两种移位运算都用0来填补移出的空位,下面举例说明。【例2-7】

采用移位运算符实现两个3位数的乘法。解题指引如图2-3所示,设a为3位乘数,用a2a1a0表示,设b为3位被乘数,用b2b1b0表示,乘法运算过程如下:乘法的最后是把5列分别求和得到5位的积。根据以上运算过程可以看出,乘法的最后也可以将最后3行代表的3个数相加,但第2行相对第1行要左移1位,第3行相对第1行要左移2位。Verilog实现代码如下:程序说明如下:(1)wire[5:0]m1,m2,m3;定义了3个中间变量,m1用于存放第1行的值,m2用于存放第2行的值,m3用于存放第3行的值。(2)本例为两个3位数相乘,我们可以

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论