China°do 第3章 Verilog语言要素 本章介绍 Verilog HDL的基本要素,包括标识符、注释、数值、编译程序指令、系统任务 和系统函数。另外,本章还介绍了 Verilog硬件描述语言中的两种数据类型 3.1标识符 Ⅴ erilog hdl中的标识符( (identifier)可以是任意一组字母、数字、$符号和_(下划线)符号的 组合,但标识符的第一个字符必须是字母或者下划线。另外,标识符是区分大小写的。以下 是标识符的几个例子 Count //与 Count不同。 RI D2 FIVES 转义标识符( escaped identifier)可以在一条标识符中包含任何可打印字符。转义标识符以 (反斜线)符号开头,以空白结尾(空白可以是一个空格、一个制表字符或换行符)。下面例举 了几个转义标识符: 7400 OutGate与 OutGate相同。 最后这个例子解释了在一条转义标识符中,反斜线和结束空格并不是转义标识符的一部 分。也就是说,标识符 OutGate和标识符 OutGate恒等。 Ⅴ erilog hdl定义了一系列保留字,叫做关键词,它仅用于某些上下文中。附录A列出了 语言中的所有保留字。注意只有小写的关键词才是保留字。例如,标识符 always(这是个关键 词)与标识符 ALWAYS(非关键词)是不同的 另外,转义标识符与关键词并不完全相同。标识符 \initial与标识符 initial(这是个关键词) 不同。注意这一约定与那些转义标识符不同 32注释 在 Verilog hdli中有两种形式的注释 /*第一种形式:可以扩展至 多行* //第二种形式:在本行结束。 3.3格式 Ⅴ erilog hdl区分大小写。也就是说大小写不同的标识符是不同的。此外, Verilog Hdl是
下载 第3章 Verilog语言要素 本章介绍Verilog HDL的基本要素,包括标识符、注释、数值、编译程序指令、系统任务 和系统函数。另外,本章还介绍了 Ve r i l o g硬件描述语言中的两种数据类型。 3.1 标识符 Verilog HDL中的标识符( i d e n t i f i e r )可以是任意一组字母、数字、 $符号和_(下划线)符号的 组合,但标识符的第一个字符必须是字母或者下划线。另外,标识符是区分大小写的。以下 是标识符的几个例子: C o u n t COUNT / /与C o u n t不同。 _ R 1 _ D 2 R 5 6 _ 6 8 F I V E $ 转义标识符(escaped identifier )可以在一条标识符中包含任何可打印字符。转义标识符以 \ (反斜线)符号开头,以空白结尾(空白可以是一个空格、一个制表字符或换行符)。下面例举 了几个转义标识符: \ 7 4 0 0 \ . * .$ \ { * * * * * * } \ ~Q \O u t G a t e 与O u t G a t e相同。 最后这个例子解释了在一条转义标识符中,反斜线和结束空格并不是转义标识符的一部 分。也就是说,标识符\ O u t G a t e 和标识符O u t G a t e恒等。 Verilog HDL定义了一系列保留字,叫做关键词,它仅用于某些上下文中。 附录A列出了 语言中的所有保留字。注意只有小写的关键词才是保留字。例如,标识符 a l w a y s (这是个关键 词)与标识符A LWAY S(非关键词)是不同的。 另外,转义标识符与关键词并不完全相同。标识符 \initial 与标识符i n i t i a l(这是个关键词) 不同。注意这一约定与那些转义标识符不同。 3.2 注释 在Verilog HDL中有两种形式的注释。 / *第一种形式:可以扩展至 多行 * / / /第二种形式:在本行结束。 3.3 格式 Verilog HDL区分大小写。也就是说大小写不同的标识符是不同的。此外, Verilog HDL是
第章 Verilog语言要素 15 自由格式的,即结构可以跨越多行编写,也可以在一行内编写。白空(新行、制表符和空格) 没有特殊意义。下面通过实例解释说明 initial begin Top =3b00l; #2 Top =3 boil; end 和下面的指令一样 Top=3’b001; 3b011 34系统任务和函数 以$字符开始的标识符表示系统任务或系统函数。任务提供了一种封装行为的机制。这种 机制可在设计的不同部分被调用。任务可以返回0个或多个值。函数除只能返回一个值以外与 任务相同。此外,函数在0时刻执行,即不允许延迟,而任务可以带有延迟。 Display ("Hi, you have reached LT today") /*$ display系统任务在新的一行中显示。*/ /该系统任务返回当前的模拟时间 系统任务和系统函数在第10章中详细讲觚 3.5编译指令 以ˆ(反引号)开始的某些标识符是编译器指令。在Ⅴ erilog语言编译时,特定的编译器指 令在整个编译过程中有效(编译过程可跨越多个文件),直到遇到其它的不同编译程序指令 完整的标准编译器指令如下 define, undef ifdefrelse, endif default neotype · include resetall drive connected drive celldefine, endcelldefine 3.5.1 define和 undef define指令用于文本替换,它很像C语言中的# define指令,如: define MAX BUs size reg MAX BUS SIZE -1:0 ] AddReg 旦 de fine指令被编译,其在整个编译过程中都有效。例如,通过另一个文件中的 define指令, MAX BUS_S/ZE能被多个文件使用 undef指令取消前面定义的宏。例如 define WORD16//建立一个文本宏替代 wire[ WORD 1] Bus
第3章 Verilog 语言要素 15 下载 自由格式的,即结构可以跨越多行编写,也可以在一行内编写。白空(新行、制表符和空格) 没有特殊意义。下面通过实例解释说明。 initial begin T o p = 3' b001; #2 T o p = 3' b011; e n d 和下面的指令一样: i n i t i a l begin T o p = 3' b001; #2 T o p = 3' b 0 1 1 ; e n d 3.4 系统任务和函数 以$字符开始的标识符表示系统任务或系统函数。任务提供了一种封装行为的机制。这种 机制可在设计的不同部分被调用。任务可以返回 0个或多个值。函数除只能返回一个值以外与 任务相同。此外,函数在0时刻执行,即不允许延迟,而任务可以带有延迟。 $d i s p l a y ("Hi, you have reached LT today"); /* $d i s p l a y 系统任务在新的一行中显示。* / $t i m e / /该系统任务返回当前的模拟时间。 系统任务和系统函数在第1 0章中详细讲解。 3.5 编译指令 以`(反引号)开始的某些标识符是编译器指令。在 Verilog 语言编译时,特定的编译器指 令在整个编译过程中有效(编译过程可跨越多个文件),直到遇到其它的不同编译程序指令。 完整的标准编译器指令如下 : • `define, `undef • `ifdef, `else, `endif • `default_nettype • `include • `resetall • `timescale • `unconnected_drive, `nounconnected_drive • `celldefine, `endcelldefine 3.5.1 `define 和`undef ` d e f i n e指令用于文本替换,它很像 C语言中的#define 指令,如: ` d e f i n e M A X _ B U S _ S I Z E 3 2 . . . r e g [ `M A X _ B U S _ S I Z E - 1:0 ] A d d R e g; 一旦 ` d e f i n e 指令被编译,其在整个编译过程中都有效。例如,通过另一个文件中的 ` d e f i n e指令,M A X_B U S_S I Z E 能被多个文件使用。 `undef 指令取消前面定义的宏。例如 : ` d e f i n e W O R D 16 //建立一个文本宏替代。 . . . w i r e [ `W O R D : 1] Bus;
16 Verilog hdl硬弹描述语言 China°Co 下载 undef wORD 在 undef编译指令后,NoRD的宏定义不再有效 3.5.2 ifdef、'ese和' endif 这些编译指令用于条件编译,如下所示: ⊥ fdef WINDows parameter WORD SIZE= 16 else parameter WORD SIZE 32 endif 在编译过程中,如果已定义了名字为 WINDOWS的文本宏,就选择第一种参数声明,否则 选择第二种参数说明 else程序指令对于' ifdef指令是可选的。 3.5.3 default nettype 该指令用于为隐式线网指定线网类型。也就是将那些没有被说明的连线定义线网类型。 default nettype wand 该实例定义的缺省的线网为线与类型。因此,如果在此指令后面的任何模块中没有说明的连 线,那么该线网被假定为线与类型 3.5.4 include inelude编译器指令用于嵌入内嵌文件的内容。文件既可以用相对路径名定义,也可以用 全路径名定义,例如 ⊥ nclude /primitives.v 编译时,这一行由文件“/. primitives.v”的内容替代 3.5.5 resetall 该编译器指令将所有的编译指令重新设置为缺省值 resetall 例如,该指令使得缺省连线类型为线网类型 3.5.6 timescale 在 Verilog hdl模型中,所有时延都用单位时间表述。使用' timescale编译器指令将时间 单位与实际时间相关联。该指令用于定义时延的单位和时延精度。' timescale编译器指令格式 为 timescale time unit /time precisie fime unit和 Itime precision由值1、10、和100以及单位s、ms、us、ns、ps和fs组成。例如 timescale lns/100ps 表示时延单位为1ns,时延精度为100ps。' timescale编译器指令在模块说明外部出现,并且影响 后面所有的时延值。例如
. . . ` u n d e f W O R D // 在` u n d e f编译指令后, W O R D的宏定义不再有效. 3.5.2 `ifdef、`else 和`endif 这些编译指令用于条件编译,如下所示: ` i f d e f W I N D O W S p a r a m e t e r WORD_SIZE = 16 ` e l s e p a r a m e t e r W O R D _ S I Z E = 32 ` e n d i f 在编译过程中,如果已定义了名字为 W I N D O W S的文本宏,就选择第一种参数声明,否则 选择第二种参数说明。 ` e l s e 程序指令对于`ifdef 指令是可选的。 3.5.3 `default_nettype 该指令用于为隐式线网指定线网类型。也就是将那些没有被说明的连线定义线网类型。 `default_nettype wand 该实例定义的缺省的线网为线与类型。因此,如果在此指令后面的任何模块中没有说明的连 线,那么该线网被假定为线与类型。 3.5.4 `include ` i n c l u d e 编译器指令用于嵌入内嵌文件的内容。文件既可以用相对路径名定义,也可以用 全路径名定义, 例如: ` i n c l u d e " . . / . . /primitives.v" 编译时,这一行由文件“. . / . . / p r i m i t i v e s . v” 的内容替代。 3.5.5 `resetall 该编译器指令将所有的编译指令重新设置为缺省值。 ` r e s e t a l l 例如,该指令使得缺省连线类型为线网类型。 3.5.6 `timescale 在Verilog HDL 模型中,所有时延都用单位时间表述。使用 ` t i m e s c a l e编译器指令将时间 单位与实际时间相关联。该指令用于定义时延的单位和时延精度。 ` t i m e s c a l e编译器指令格式 为: ` t i m e s c a l e t i m e _ u n i t / t i m e _ p r e c i s i o n t i m e _ u n i t 和t i m e _ p re c i s i o n 由值1、1 0、和1 0 0以及单位s、m s、u s、n s、p s和f s组成。例如: ` t i m e s c a l e 1 n s / 1 0 0 p s 表示时延单位为1ns, 时延精度为1 0 0 p s。`timescale 编译器指令在模块说明外部出现 , 并且影响 后面所有的时延值。例如: 16 Verilog HDL 硬件描述语言 下载
中M 第章 Verilog语言要素 17 timescale lns/ 100ps module AndFunc (2, A, B)i and#(5.22,6.17)A1(z,A,B); //规定了上升及下降时延值。 endmodule 编译器指令定义时延以ns为单位,并且时延精度为1/10ns(100ps)。因此,时延值52对应 52ns,时延6.17对应62ns。如果用如下的' timescale程序指令代替上例中的编译器指令 timescale 10ns/lns 那么522对应52ns,6.17对应62ns 在编译过程中,' timescale指令影响这一编译器指令后面所有模块中的时延值,直至遇到 另一个' timescale指令或' reseta指令。当一个设计中的多个模块带有自身的' timescale编译指 令时将发生什么?在这种情况下,模拟器总是定位在所有模块的最小时延精度上,并且所有 时延都相应地换算为最小时延精度。例如, timescale lns/ 100ps module AndFunc (Z, A, B)i output z input A, B and#(5.22,6.17)A1(2,A,B) endmodule timescale 10ns/ lns module T reg PutA, PutE wire Geto: begin PutB =0 #5.21 PutB #10.4PutA=1 #15 PutB=0 AndFunc AFI(Geto, PutA, PutB endmodule 这个例子中,每个模块都有自身的' timescale编译器指令。' timescale编译器指令第一次 应用于时延。因此,在第一个模块中,5.22对应5.2ns,6.17对应62ns;在第二个模块中521对 应52ns,10.4对应104ns,15对应150ns。如果仿真模块TB,设计中的所有模块最小时间精度为 I00ps。因此,所有延迟(特别是模块TB中的延迟)将换算成精度为100ps。延迟52ns现在 对应520*100ps,104对应1040*100ps,150对应1500*100ps。更重要的是,仿真使用100ps 为时间精度。如果仿真模块 AndFunc,由于模块TB不是模块 AddFunc的子模块,模块TB中的 timescale程序指令将不再有效
` t i m e s c a l e 1ns/ 100ps m o d u l e A n d F u n c (Z, A, B) ; o u t p u t Z; i n p u t A, B; a n d # (5.22, 6.17 ) A l (Z, A, B); / /规定了上升及下降时延值。 e n d m o d u l e 编译器指令定义时延以 n s为单位,并且时延精度为 1/10 ns(100 ps)。因此,时延值5 . 2 2对应 5.2 ns, 时延6 . 1 7对应6.2 ns。如果用如下的` t i m e s c a l e程序指令代替上例中的编译器指令 , ` t i m e s c a l e 1 0 n s / 1 n s 那么5 . 2 2对应52ns, 6.17对应6 2 n s。 在编译过程中,` t i m e s c a l e指令影响这一编译器指令后面所有模块中的时延值,直至遇到 另一个` t i m e s c a l e指令或` r e s e t a l l指令。当一个设计中的多个模块带有自身的 ` t i m e s c a l e编译指 令时将发生什么?在这种情况下,模拟器总是定位在所有模块的最小时延精度上,并且所有 时延都相应地换算为最小时延精度。例如, ` t i m e s c a l e 1ns/ 100ps m o d u l e A n d F u n c (Z, A, B) ; o u t p u t Z; i n p u t A, B; a n d # (5.22, 6.17 ) A l (Z, A, B) ; e n d m o d u l e ` t i m e s c a l e 10ns/ 1ns m o d u l e T B; r e g PutA, PutB; w i r e G e t O; i n i t i a l b e g i n P u tA = 0; P u t B = 0; #5.21 P u t B = 1; #10.4 P u t A = 1; #15 P u t B = 0; e n d A n d F u n c A F 1(GetO, PutA, PutB) ; e n d m o d u l e 在这个例子中,每个模块都有自身的 ` t i m e s c a l e编译器指令。` t i m e s c a l e编译器指令第一次 应用于时延。因此,在第一个模块中, 5 . 2 2对应5.2 ns, 6.17对应6.2 ns; 在第二个模块中5 . 2 1对 应52 ns, 10.4对应104 ns, 15对应150 ns。如果仿真模块T B,设计中的所有模块最小时间精度为 100 ps。因此,所有延迟(特别是模块 T B中的延迟)将换算成精度为 100 ps。延迟52 ns现在 对应5 2 0*100 ps,1 0 4对应1 0 4 0*100 ps,1 5 0对应1 5 0 0*100 ps。更重要的是,仿真使用 100 ps 为时间精度。如果仿真模块 A n d F u n c,由于模块T B不是模块A d d F u n c的子模块,模块 T B中的 ` t i m e s c a l e程序指令将不再有效。 第3章 Verilog 语言要素 17 下载
18 Verilog hdl硬弹描述语言 China°bCo 下载 3.5.7 unconnected drive nonconnected drive 在模块实例化中,出现在这两个编译器指令间的任何未连接的输入端口或者为正偏电路 状态或者为反偏电路状态。 unconnected drive pulll /*在这两个程序指令间的所有未连接的输入端口为正偏电路状态(连接到高电平)+/ nonconnected drive unconnected drive pullo /*在这两个程序指令间的所有未连接的输入端口为反偏电路状态(连接到低电平)+ nonconnected drive 3.58‘ celldefine和' endcelldefine 这两个程序指令用于将模块标记为单元模块。它们表示包含模块定义,如下例所示。 celldefine module FDi CK, 4 endcelldefine 某些PLI例程使用单元模块 3.6值集合 Ⅴ erilog hdl有下列四种基本的值: 1)0:逻辑0或“假 2)1:逻辑1或“真” 3)x:未知 )z:高阻 注意这四种值的解释都内置于语言中。如一个为z的值总是意味着高阻抗,一个为0的值 通常是指逻辑0。 在门的输入或一个表达式中的为“z”的值通常解释成“x”。此外,x值和z值都是不分大 小写的,也就是说,值0x1z与值0X1Z相同。 Verilog hdl中的常量是由以上这四类基本值组成 的。 Ⅴ erilog hdl中有三类常量 1)整型 2)实数型 3)字符串型 下划线符号()可以随意用在整数或实数中,它们就数量本身没有意义。它们能用来提 高易读性:唯一的限制是下划线符号不能用作为首字符。 36.1整型数 整型数可以按如下两种方式书写
18 Verilog HDL 硬件描述语言 下载 3.5.7 `unconnected_drive和`nounconnected_drive 在模块实例化中,出现在这两个编译器指令间的任何未连接的输入端口或者为正偏电路 状态或者为反偏电路状态。 ` u n c o n n e c t e d _ d r i v e p u l l 1 . . . / *在这两个程序指令间的所有未连接的输入端口为正偏电路状态(连接到高电平) * / ` n o u n c o n n e c t e d _ d r i v e `unconnected_drive pull0 . . . / *在这两个程序指令间的所有未连接的输入端口为反偏电路状态(连接到低电平) * / ` n o u n c o n n e c t e d _ d r i v e 3.5.8 `celldefine 和 `endcelldefine 这两个程序指令用于将模块标记为单元模块。它们表示包含模块定义,如下例所示。 ` c e l l d e f i n e m o d u l e F D 1 S 3 A X (D, CK, Z) ; . . . e n d m o d u l e ` e n d c e l l d e f i n e 某些P L I例程使用单元模块。 3.6 值集合 Verilog HDL有下列四种基本的值: 1) 0:逻辑0或“假” 2) 1:逻辑1或“真” 3) x:未知 4) z:高阻 注意这四种值的解释都内置于语言中。如一个为 z的值总是意味着高阻抗,一个为 0的值 通常是指逻辑0。 在门的输入或一个表达式中的为“ z”的值通常解释成“ x”。此外,x值和z值都是不分大 小写的,也就是说,值0 x 1 z与值0 X 1 Z相同。Verilog HDL中的常量是由以上这四类基本值组成 的。 Verilog HDL中有三类常量: 1) 整型 2) 实数型 3) 字符串型 下划线符号(_)可以随意用在整数或实数中,它们就数量本身没有意义。它们能用来提 高易读性;唯一的限制是下划线符号不能用作为首字符。 3.6.1 整型数 整型数可以按如下两种方式书写: