《Verilog HDL3语言要素.ppt》由会员分享,可在线阅读,更多相关《Verilog HDL3语言要素.ppt(36页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第3章 Verilog的语言要素本章介绍本章介绍VerilogHDL的基本要素,包括标识符、注释、的基本要素,包括标识符、注释、数值、编译程序指令、系统任务和系统函数。另外,本章还数值、编译程序指令、系统任务和系统函数。另外,本章还介绍了介绍了Verilog硬件描述语言中的两种数据类型。硬件描述语言中的两种数据类型。3.1标识符标识符VerilogHDL中的标识符中的标识符(identifier)可以是任意一组字母、数字、可以是任意一组字母、数字、$符号和符号和_(下划线下划线)符号的组合,但标识符的第一个字符必须是字母或者下符号的组合,但标识符的第一个字符必须是字母或者下划线。另外,标识符是
2、区分大小写的。以下是标识符的几个例子:划线。另外,标识符是区分大小写的。以下是标识符的几个例子:转义标识符转义标识符(escapedidentifier)可以在一条标识符中包含任可以在一条标识符中包含任何可打印字符。转义标识符以何可打印字符。转义标识符以(反斜线反斜线)符号开头,以空白结尾(空符号开头,以空白结尾(空白可以是一个空格、一个制表字符或换行符)。下面例举了几个转白可以是一个空格、一个制表字符或换行符)。下面例举了几个转义标识符:义标识符:反斜线和结束空格并不是转义标识符的一部分。Verilog HDL Verilog HDL定义了一系列保留字,叫做关键词,仅用于某些上下文定义了一系
3、列保留字,叫做关键词,仅用于某些上下文中。注意只有小写的关键词才是保留字。例如,标识符中。注意只有小写的关键词才是保留字。例如,标识符always(这是个这是个关键词关键词)与标识符与标识符ALWAYS(非关键词非关键词)是不同的。另外,转义标识符与关是不同的。另外,转义标识符与关键词并不完全相同。标识符键词并不完全相同。标识符initial与标识符与标识符initial(这是个关键词)(这是个关键词)不同。不同。3.2注释注释在在VerilogHDL中有两种形式的注释。中有两种形式的注释。/*第一种形式第一种形式:可以扩展至可以扩展至多行多行*/第二种形式第二种形式:在本行结束。在本行结束。
4、3.3格式格式VerilogHDL区分大小写。也就是说大小写不同的标识符是不同的。区分大小写。也就是说大小写不同的标识符是不同的。此外,此外,VerilogHDL是自由格式的,即结构可以跨越多行编写,也可以是自由格式的,即结构可以跨越多行编写,也可以在一行内编写。白空(新行、制表符和空格)没有特殊意义。下面通过在一行内编写。白空(新行、制表符和空格)没有特殊意义。下面通过实例解释说明。实例解释说明。3.4系统任务和函数系统任务和函数以以$字符开始的标识符表示系统任务或系统函数。任务提供了一种封字符开始的标识符表示系统任务或系统函数。任务提供了一种封装行为的机制。这种机制可在设计的不同部分被调用
5、。任务可以装行为的机制。这种机制可在设计的不同部分被调用。任务可以返回返回0个个或多个值或多个值。函数除只能。函数除只能返回一个值返回一个值以外与任务相同。此外,函数在以外与任务相同。此外,函数在0时刻时刻执行执行,即不允许延迟,而任务可以,即不允许延迟,而任务可以带有延迟带有延迟。3.5编译指令编译指令以以(反引号)开始的某些标识符是编译器指令。在(反引号)开始的某些标识符是编译器指令。在Verilog语言编译语言编译时,特定的编译器指令在整个编译过程中有效(编译过程可跨越多个文件)时,特定的编译器指令在整个编译过程中有效(编译过程可跨越多个文件),直到遇到其它的不同编译程序指令。完整的标准
6、编译器指令如下,直到遇到其它的不同编译程序指令。完整的标准编译器指令如下:3.5.1 define和和undefdefine指令用于文本替换,它很像指令用于文本替换,它很像C语言中的语言中的#define指令,如指令,如:一旦一旦define指令被编译,其在整个编译过程中都有效。例如,通过指令被编译,其在整个编译过程中都有效。例如,通过另一个文件中的另一个文件中的define指令,指令,MAX_BUS_SIZE 能被多个文件使用。能被多个文件使用。undef指令取消前面定义的宏。指令取消前面定义的宏。3.5.2ifdef、else和和endif这些编译指令用于条件编译,如下所示:这些编译指令用
7、于条件编译,如下所示:在编译过程中,如果已定义了名字为在编译过程中,如果已定义了名字为WINDOWS的文本宏,就选择的文本宏,就选择第一种参数声明,否则选择第二种参数说明。第一种参数声明,否则选择第二种参数说明。3.5.3default_nettype该指令用于为隐式线网指定线网类型。也就是将那些没有被说明的该指令用于为隐式线网指定线网类型。也就是将那些没有被说明的连线定义线网类型。连线定义线网类型。该实例定义的缺省的线网为线与类型。因此,如果在此指令后面的任何模块中没有说明的连线,那么该线网被假定为线与类型。3.5.4includeinclude编译器指令用于嵌入内嵌文件的内容。文件既可以用
8、相对编译器指令用于嵌入内嵌文件的内容。文件既可以用相对路径名定义,也可以用全路径名定义路径名定义,也可以用全路径名定义,例如例如:编译时,这一行由文件“././primitives.v”的内容替代。3.5.5resetall该编译器指令将所有的编译指令重新设置为缺省值。该编译器指令将所有的编译指令重新设置为缺省值。resetall例如,该指令使得缺省连线类型为线网类型。例如,该指令使得缺省连线类型为线网类型。3.5.6timescale在在VerilogHDL模型中,所有时延都用单位时间表述。使用模型中,所有时延都用单位时间表述。使用timescale编译器指令将时间单位与实际时间相关联。该指
9、令用于定义时延的单位和编译器指令将时间单位与实际时间相关联。该指令用于定义时延的单位和时延精度。时延精度。timescale编译器指令格式为:编译器指令格式为:time_unit 和和time_precision 由值由值1、10、和、和100以及单位以及单位s、ms、us、ns、ps和和fs组成。组成。timescale编译器指令在模块说明外部出现编译器指令在模块说明外部出现,并并且影响后面所有的时延值。例如且影响后面所有的时延值。例如:时延分别是时延分别是5.2ns,6.2ns在编译过程中,在编译过程中,timescale指指令影响这一编译器指令后面令影响这一编译器指令后面所有所有模模块中
10、的时延值,直至遇到另一个块中的时延值,直至遇到另一个timescale指令或指令或resetall指令指令。当一个设计中的多个模块带有自身当一个设计中的多个模块带有自身的的timescale编译指令时将发生什编译指令时将发生什么?在这种情况下,模拟器总是定么?在这种情况下,模拟器总是定位在所有模块的最小时延精度上,位在所有模块的最小时延精度上,并且所有时延都相应地换算为最小并且所有时延都相应地换算为最小时延精度。例如,时延精度。例如,时延时延5.2ns,6.2ns时延时延52ns,104ns,150ns精度是100ps3.5.7unconnected_drive和和nounconnected_
11、drive3.5.8celldefine和和endcelldefine这两个程序指令用于将模块标记为单元模块。它们表示包含模块定这两个程序指令用于将模块标记为单元模块。它们表示包含模块定义,如下例所示:义,如下例所示:3.6值集合值集合VerilogHDL有下列四种基本的值:有下列四种基本的值:1)0:逻辑:逻辑0或或“假假”2)1:逻辑:逻辑1或或“真真”3)x:未知:未知4)z:高阻:高阻在门的输入或一个表达式中的为在门的输入或一个表达式中的为“z”的值通常解释成的值通常解释成“x”。此外,。此外,x值和值和z值都是不分大小写的,也就是说,值值都是不分大小写的,也就是说,值0 x1z与值与
12、值0X1Z相同。相同。(1 1)任何值和)任何值和“1 1”进行进行“或或”操作,结果都是操作,结果都是1 1;(2 2)任何值和)任何值和“0 0”进行进行“与与”操作,结果都是操作,结果都是0 0;(3 3)除了()除了(1 1)和()和(2 2)的情况外,只要有)的情况外,只要有x x或者或者z z参与逻辑运算,结参与逻辑运算,结果都是果都是x x。VerilogHDL中有三类常量:中有三类常量:1)整型整型2)实数型实数型3)字符串型字符串型3.6.1整型数整型数整型数可以按如下两种方式书写:整型数可以按如下两种方式书写:1)简单的十进制数格式简单的十进制数格式2)基数格式基数格式1.
13、简单的十进制格式简单的十进制格式这种形式的整数定义为带有一个可选的这种形式的整数定义为带有一个可选的“”(一元)或(一元)或“”(一元)操作符的数字序列。下面是这种简易十进制形式整数的例(一元)操作符的数字序列。下面是这种简易十进制形式整数的例子。子。2.基数表示法基数表示法这种形式的整数格式为:这种形式的整数格式为:size定义以位计的常量的位长;定义以位计的常量的位长;base为为o或或O(表示八进制),(表示八进制),b或或B(表示二进制),(表示二进制),d或或D(表示十进制),(表示十进制),h或或H(表示十六进制)之一;(表示十六进制)之一;value是基于是基于base的值的数字
14、序列。值的值的数字序列。值x和和z以及十六进制中的以及十六进制中的a到到f不区不区分大小写。分大小写。5O375位八进制数位八进制数4D24位十进制数位十进制数4B1x_014位二进制数位二进制数7Hx7位位x(扩展的扩展的x),即即xxxxxxx4hZ4位位z(扩展的扩展的z),即即zzzz4d-4非法:数值不能为负非法:数值不能为负8h2A在位长和字符之间在位长和字符之间,以及基数和数值之间允许出现空格以及基数和数值之间允许出现空格3b001非法非法:和基数和基数b之间不允许出现空格之间不允许出现空格(2+3)b10非法非法:位长不能够为表达式位长不能够为表达式sizebasevalue注
15、意,注意,x(或(或z)在十六进制值中代表)在十六进制值中代表4位位x(或(或z),在八进),在八进制中代表制中代表3位位x(或(或z),在二进制中代表),在二进制中代表1位位x(或(或z)。)。基数格式计数形式的数通常为无符号数。这种形式的整型数的长度定基数格式计数形式的数通常为无符号数。这种形式的整型数的长度定义是可选的。如果没有定义一个整数型的长度,数的长度为相应值中定义义是可选的。如果没有定义一个整数型的长度,数的长度为相应值中定义的位数。下面是两个例子:的位数。下面是两个例子:如果定义的长度比为常量指定的长度长,通常在左边填如果定义的长度比为常量指定的长度长,通常在左边填0补位。但是
16、补位。但是如果数最左边一位为如果数最左边一位为x或或z,就相应地用,就相应地用x或或z在左边补位。例如:在左边补位。例如:如果长度定义得更小,那么最左边的位相应地被截断。例如:如果长度定义得更小,那么最左边的位相应地被截断。例如:o7219位八进制数位八进制数hAF8位十六进制数位十六进制数10b10左边添左边添0占位占位,000000001010bx0 x1左边添左边添x占位占位,xxxxxxx0 x13b1001_0011与与3b011相等。相等。5H0FFF与与5H1F相等。相等。3.6.2实数实数实数可以用下列两种形式定义:实数可以用下列两种形式定义:1)十进制计数法;例如十进制计数法
17、;例如2)科学计数法;科学计数法;这种形式的实数举例如下:这种形式的实数举例如下:3.6.3字符串字符串字符串是双引号内的字符序列。字符串不能分成多行书写。例如字符串是双引号内的字符序列。字符串不能分成多行书写。例如:用用8 8位位ASCIIASCII值表示的字符可看作是无符号整数。因此字符串是值表示的字符可看作是无符号整数。因此字符串是8 8位位ASCIIASCII值的序列。为存储字符串值的序列。为存储字符串“INTERNAL ERRORINTERNAL ERROR”,变量需要,变量需要8*148*14位。位。3.7数据类型数据类型VerilogHDL有两大类数据类型。有两大类数据类型。1)
18、线网类型。线网类型。nettype表示表示Verilog结构化元件间的物理连线。它的值由结构化元件间的物理连线。它的值由驱动元件的值决定,例如连续赋值或门的输出。如果没有驱动元件连接驱动元件的值决定,例如连续赋值或门的输出。如果没有驱动元件连接到线网,线网的缺省值为到线网,线网的缺省值为z。2)寄存器类型。寄存器类型。registertype表示一个抽象的数据存储单元,它只能在表示一个抽象的数据存储单元,它只能在always语句和语句和initial语句中被赋值,并且它的值从一个赋值到另一个赋值语句中被赋值,并且它的值从一个赋值到另一个赋值被保存下来。寄存器类型的变量具有被保存下来。寄存器类型
19、的变量具有x的缺省值。的缺省值。3.7.1线网类型线网类型线网数据类型包含下述不同种类的线网子类型。线网数据类型包含下述不同种类的线网子类型。net_kind 是上述线网类型的一种。是上述线网类型的一种。msb和和lsb是用于定是用于定义线网范围的常量表达式;范围定义是可选的;如果没有定义线网范围的常量表达式;范围定义是可选的;如果没有定义范围,缺省的线网类型为义范围,缺省的线网类型为1位。下面是线网类型说明实例。位。下面是线网类型说明实例。当一个线网有多个驱动器时,即对一个线网有多个赋值当一个线网有多个驱动器时,即对一个线网有多个赋值时,不同的线网产生不同的行为。例如,时,不同的线网产生不同
20、的行为。例如,Rde有两个驱动有两个驱动源,由于它是线或线源,由于它是线或线网,网,Rde的有效值由的有效值由使用驱动源的值)的使用驱动源的值)的线或线或(wor)表决定。表决定。例如,如果第一个右侧例如,如果第一个右侧表达式的值为表达式的值为01x,并且并且第二个右测表达式的值第二个右测表达式的值为为11z,Cla?1.wire和和tri线网线网用于连接单元的连线是最常见的线网类型。连线与三态线用于连接单元的连线是最常见的线网类型。连线与三态线(tri)网语网语法和语义一致;三态线可以用于描述多个驱动源驱动同一根线的线网法和语义一致;三态线可以用于描述多个驱动源驱动同一根线的线网类型;并且没
21、有其他特殊的意义。类型;并且没有其他特殊的意义。两个驱动源的值两个驱动源的值(右侧表达式的值)用(右侧表达式的值)用于在上表中索引,以便于在上表中索引,以便决定决定Cla的有效值。的有效值。Clax1x2.wor和和trior线网线网线或指如果某个驱动源为线或指如果某个驱动源为1,那么线网的值也为,那么线网的值也为1。线或和三态线。线或和三态线或或(trior)在语法和功能上是一致的。在语法和功能上是一致的。3.wand和和triand线网线网线与线与(wand)网指如果某个驱动源为网指如果某个驱动源为0,那么线网的值为,那么线网的值为0。线与和。线与和三态线与三态线与(triand)网在语法
22、和功能上是一致的。网在语法和功能上是一致的。4.trireg线网线网此线网存储数值(类似于寄存器),并且用于电容节点的建模。此线网存储数值(类似于寄存器),并且用于电容节点的建模。当三态寄存器当三态寄存器(trireg)的所有驱动源都处于高阻态,也就是说,值为的所有驱动源都处于高阻态,也就是说,值为z时,三态寄存器线网保存作用在线网上的最后一个值。此外,三态寄时,三态寄存器线网保存作用在线网上的最后一个值。此外,三态寄存器线网的缺省初始值为存器线网的缺省初始值为x。5.tri0和和tri1线网线网这类线网可用于线逻辑的建模,即线网有多于一个驱动源。这类线网可用于线逻辑的建模,即线网有多于一个驱
23、动源。tri0(tri1)线网的特征是,若无驱动源驱动,它的值为)线网的特征是,若无驱动源驱动,它的值为0(tri1的值为的值为1)。)。6.supply0和和supply1线网线网supply0用于对用于对“地地”建模,即低电平建模,即低电平0;supply1网用于对电源建网用于对电源建模,即高电平模,即高电平1;例如;例如:3.7.2未说明的线网未说明的线网在在VerilogHDL中,有可能不必声明某种线网类型。在这样的情况中,有可能不必声明某种线网类型。在这样的情况下,缺省线网类型为下,缺省线网类型为1位线网。位线网。可以使用可以使用default_nettype编译器指令改变这一隐式线
24、网说明方式。编译器指令改变这一隐式线网说明方式。使用方法如下:使用方法如下:例如,带有下列编译器指令:例如,带有下列编译器指令:任何未被说明的网缺省为任何未被说明的网缺省为1位线与网。位线与网。3.7.3向量和标量线网向量和标量线网在定义向量线网时可选用关键词在定义向量线网时可选用关键词scalared或或vectored。如果一个线。如果一个线网定义时使用了关键词网定义时使用了关键词vectored,那么就不允许位选择和部分选择该线那么就不允许位选择和部分选择该线网。换句话说,必须对线网整体赋值(位选择和部分选择在下一章中讲网。换句话说,必须对线网整体赋值(位选择和部分选择在下一章中讲解)。
25、例如解)。例如:如果没有定义关键词,缺省值为标量。如果没有定义关键词,缺省值为标量。3.7.4寄存器类型寄存器类型有有5种不同的寄存器类型。种不同的寄存器类型。reg integer time real realtime1.reg寄存器类型寄存器类型寄存器数据类型寄存器数据类型reg是最常见的数据类型。是最常见的数据类型。reg类型使用保留字类型使用保留字reg加以说明,形式如下:加以说明,形式如下:msb和和lsb定义了范围,并且均为常数值表达式。范围定义是可选的;定义了范围,并且均为常数值表达式。范围定义是可选的;如果没有定义范围,缺省值为如果没有定义范围,缺省值为1位寄存器。位寄存器。寄
26、存器可以取任意长度。寄存器中的值通常被解释为无符号数寄存器可以取任意长度。寄存器中的值通常被解释为无符号数,例如:例如:2.存储器存储器 存储器是一个寄存器数组。存储器使用如下方式说明:存储器是一个寄存器数组。存储器使用如下方式说明:reg3:0Sat;/Sat为为4位寄存器。位寄存器。regCnt;/1位寄存器。位寄存器。reg1:32Kisp,Pisp,Lisp;reg1:4Comb;.Comb=-2;/Comb的值为的值为14(1110),),1110是是2的补码。的补码。Comb=5;/Comb的值为的值为5(0101)。)。注意存储器属于寄存器数组类型。线网数据类型没有相应的存注意存
27、储器属于寄存器数组类型。线网数据类型没有相应的存储器类型。储器类型。单个寄存器说明既能够用于说明寄存器类型,也可以用于说明单个寄存器说明既能够用于说明寄存器类型,也可以用于说明存储器类型。存储器类型。RamPar是存储器,是是存储器,是16个个8位寄存器数组,而位寄存器数组,而DataReg是是8位寄存器。位寄存器。在赋值语句中需要注意如下区别:存储器赋值不能在一条赋值语句在赋值语句中需要注意如下区别:存储器赋值不能在一条赋值语句中完成,但是寄存器可以。因此在存储器被赋值时,需要定义一个索引。中完成,但是寄存器可以。因此在存储器被赋值时,需要定义一个索引。下例说明它们之间的不同。下例说明它们之
28、间的不同。有一种存储器赋值的方法是分别对存储器中的每个字赋值。例如:有一种存储器赋值的方法是分别对存储器中的每个字赋值。例如:为存储器赋值的另一种方法是使用系统任务:为存储器赋值的另一种方法是使用系统任务:1)$readmemb(加载二进制值)(加载二进制值)2)$readmemh(加载十六进制值)(加载十六进制值)这些系统任务从指定的文本文件中读取数据并加载到存储器。文本这些系统任务从指定的文本文件中读取数据并加载到存储器。文本文件必须包含相应的二进制或者十六进制数。例如:文件必须包含相应的二进制或者十六进制数。例如:存储器存储器文件中必须包含二文件中必须包含二进制值,也可以包进制值,也可以
29、包含空白空间和注释含空白空间和注释下面是文件中可能内容的实例。下面是文件中可能内容的实例。系统任务系统任务$readmemb促使从索引促使从索引7即即RomB最左最左边的字索引,开始读取值。如果只加载存储器的一部边的字索引,开始读取值。如果只加载存储器的一部分,值域可以在分,值域可以在$readmemb方法中显式定义。例如:方法中显式定义。例如:Romb5Romb4Romb3在这种情况下,在这种情况下,值被读入存储器值被读入存储器指定的地址。指定的地址。当只定义开始值时,连续读取直当只定义开始值时,连续读取直至到达存储器右端索引边界。例如:至到达存储器右端索引边界。例如:3.Integer寄存
30、器类型寄存器类型整数寄存器包含整数值。整数寄存器可以作为普通寄存器使用,典整数寄存器包含整数值。整数寄存器可以作为普通寄存器使用,典型应用为高层次行为建模。使用整数型说明形式如下:型应用为高层次行为建模。使用整数型说明形式如下:msb和和lsb是定义整数数组界限的常量表达式,数组界限的定义是可是定义整数数组界限的常量表达式,数组界限的定义是可选的。注意容许无位界限的情况。一个整数最少容纳选的。注意容许无位界限的情况。一个整数最少容纳32位。但是具体实位。但是具体实现可提供更多的位。下面是整数说明的实例。现可提供更多的位。下面是整数说明的实例。一个整数型寄存器可存储有符号数,并且算术操作符提供一
31、个整数型寄存器可存储有符号数,并且算术操作符提供2的补码运的补码运算结果。算结果。整数不能作为位向量访问。例如,对于上面的整数整数不能作为位向量访问。例如,对于上面的整数B的的说明,说明,B6和和B20:10是非法的一种截取位值的方法是将整数赋值给一般的是非法的一种截取位值的方法是将整数赋值给一般的reg类型变量,然后从中选取相应的位,如下所示:类型变量,然后从中选取相应的位,如下所示:上例说明了如何通过简单的赋值将整数转换为位向量。类型转换自上例说明了如何通过简单的赋值将整数转换为位向量。类型转换自动完成,不必使用特定的函数。从位向量到整数的转换也可以通过赋值动完成,不必使用特定的函数。从位
32、向量到整数的转换也可以通过赋值完成。例如完成。例如:注意赋值注意赋值总是从最右端的总是从最右端的位向最左边的位位向最左边的位进行;任何多余进行;任何多余的位被截断。的位被截断。4.time类型类型time类型的寄存器用于存储和处理时间。类型的寄存器用于存储和处理时间。time类型的寄存器使类型的寄存器使用下述方式加以说明。用下述方式加以说明。msb和和lsb是表明范围界限的常量表达式。如果未定义界限,每个标是表明范围界限的常量表达式。如果未定义界限,每个标识符存储一个至少识符存储一个至少64位的时间值。时间类型的寄存器只存储无符号数。位的时间值。时间类型的寄存器只存储无符号数。例如例如:5.r
33、eal和和realtime类型类型实数寄存器(或实数时间寄存器)使用如下方式说明:实数寄存器(或实数时间寄存器)使用如下方式说明:real说明的变量的缺省值为说明的变量的缺省值为0。不允许对。不允许对real声明值域、位界限或字声明值域、位界限或字节界限。当将值节界限。当将值x和和z赋予赋予real类型寄存器时,这些值作类型寄存器时,这些值作0处理。处理。RamCnt在赋值后在赋值后的值为的值为b01010。3.8参数参数参数是一个常量。参数经常用于定义时延和变量的宽度。使用参数参数是一个常量。参数经常用于定义时延和变量的宽度。使用参数说明的参数只被赋值一次。参数说明形式如下:说明的参数只被赋值一次。参数说明形式如下:参数值也可以在编译时被改变。改变参数值可以使用参数定义语句参数值也可以在编译时被改变。改变参数值可以使用参数定义语句或通过在模块初始化语句中定义参数值。或通过在模块初始化语句中定义参数值。