📄 verilog_3.htm
字号:
<TBODY>
<TR>
<TD class=nav width=252><A
href="http://www.mcuok.com/index.php?action=forum?action=forum"><IMG
alt=飞翔单片机技术站点 src="verilog_3.files/logo1.gif" border=0></A></TD>
<TD class=nav align=middle><A href="http://www.mcuok.com/index.php"><IMG
alt=飞翔电子 src="verilog_3.files/top1.gif" border=1></A></TD>
<TD align=middle width=120><A style="LINE-HEIGHT: 18px"
href="http://bbs.mcuok.com/" target=_blank>电子论坛</A><BR><A
style="COLOR: #ff9900; LINE-HEIGHT: 18px"
href="javascript:openwin2('contract.php');">在线留言</A><BR><A
style="LINE-HEIGHT: 18px"
href="javascript:openwin2('aboutus.php');">关于我们</A></TD></TR>
<TR>
<TD bgColor=#cccccc colSpan=3 height=2></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=760 align=center bgColor=#ffffff
border=0>
<TBODY>
<TR>
<TD height=5></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=760 align=center>
<TBODY>
<TR>
<TD width="35%"><IMG alt=点击这里把本页输出到打印机! src="verilog_3.files/print.gif"
border=0> <A
href="http://www.mcuok.com/viewthread.php?fid=9&tid=274&action=printable">打印此页</A>
</TD>
<TD align=middle width="30%"><A
href="http://www.mcuok.com/viewthread.php?fid=9&tid=273"><IMG
src="verilog_3.files/prev.gif" border=0> 上一主题</A> <A
href="javascript:history.back(1);">返回前页</A> <A
href="http://www.mcuok.com/viewthread.php?fid=9&tid=275">下一主题 <IMG
src="verilog_3.files/next.gif" border=0></A></TD>
<TD class=post align=right width="35%">2005年08月05日 星期五</TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=760 align=center border=0>
<TBODY>
<TR>
<TD bgColor=#a0b8d0>
<TABLE cellSpacing=1 cellPadding=6 width="100%" border=0>
<TBODY>
<TR>
<TD class=header width="1%"></TD>
<TD class=header>文章标题 >> 中文版Verilog HDL简明教程:第3章 Verilog语言要素</TD>
<TD width="1%"></TD></TR>
<TR bgColor=#ffffff>
<TD vAlign=top rowSpan=3><!--<span class="postauthor">zjw</span><br /><br /><div><center><img src="./pic/Image18.gif"><br /><br />管理员<br /><img src="images/star.gif"><img src="images/star.gif"><img src="images/star.gif"><img src="images/star.gif"><img src="images/star.gif"><img src="images/star.gif"><img src="images/star.gif"><img src="images/star.gif"><br /><br /></center><br />贴子数量 : 471<br />注册日期 : 1/6/2003<br />在线情况 : <b>离线</b></div><br />--></TD>
<TD class=tablerow vAlign=top align=middle><IMG
src="verilog_3.files/bigsmile.gif"> 发表于: 6/22/2003 - 15:14</TD>
<TD vAlign=top rowSpan=3></TD></TR>
<TR bgColor=#ffffff>
<TD vAlign=top height=120>本章介绍Verilog
HDL的基本要素,包括标识符、注释、数值、编译程序指令、系统任务和系统函数。另外,本章还介绍了Verilog硬件描述语言中的两种数据类型。<BR><BR>3.1
标识符<BR><BR> Verilog
HDL中的标识符(identifier)可以是任意一组字母、数字、$符号和_(下划线)符号的组合,但标识符的第一个字符必须是字母或者下划线。另外,标识符是区分大小写的。以下是标识符的几个例子:<BR><BR>Count<BR>COUNT
//与Count不同。<BR>_R1_D2<BR>R56_68<BR>FIVE$<BR><BR> 转义标识符(escaped
identifier )可以在一条标识符中包含任何可打印字符。转义标识符以\
(反斜线)符号开头,以空白结尾(空白可以是一个空格、一个制表字符或换行符)。下面例举了几个转义标识符:<BR><BR>\7400<BR>\.*.$<BR>\{******}<BR>\~Q<BR>\OutGate
与OutGate相同。<BR><BR> 最后这个例子解释了在一条转义标识符中,反斜线和结束空格并不是转义标识符的一部分。也就是说,标识符\OutGate
和标识符OutGate恒等。<BR> Verilog HDL定义了一系列保留字,叫做关键词,它仅用于某些上下文中。
附录A列出了语言中的所有保留字。注意只有小写的关键词才是保留字。例如,标识符always(这是个关键词)与标识符ALWAYS(非关键词)是不同的。<BR> 另外,转义标识符与关键词并不完全相同。标识符\initial
与标识符initial(这是个关键词)不同。注意这一约定与那些转义标识符不同。<BR><BR>3.2
注释<BR><BR> 在Verilog HDL中有两种形式的注释。<BR><BR>/*第一种形式:可以扩展至<BR>多行
*/<BR><BR>//第二种形式:在本行结束。<BR><BR>3.3 格式<BR><BR> Verilog
HDL区分大小写。也就是说大小写不同的标识符是不同的。此外,Verilog
HDL是自由格式的,即结构可以跨越多行编写,也可以在一行内编写。白空(新行、制表符和空格)没有特殊意义。下面通过实例解释说明。<BR><BR>initial
begin Top = 3' b001; #2 Top = 3' b011;
end<BR><BR>和下面的指令一样:<BR><BR>initial<BR>begin <BR>Top = 3' b001;
<BR>#2 Top = 3' b011;<BR>end<BR><BR>3.4
系统任务和函数<BR><BR> 以$字符开始的标识符表示系统任务或系统函数。任务提供了一种封装行为的机制。这种机制可在设计的不同部分被调用。任务可以返回0个或多个值。函数除只能返回一个值以外与任务相同。此外,函数在0时刻执行,即不允许延迟,而任务可以带有延迟。<BR><BR>$display
("Hi, you have reached LT today");<BR>/* $display
系统任务在新的一行中显示。*/<BR>$time<BR>//该系统任务返回当前的模拟时间。<BR><BR> 系统任务和系统函数在第10章中详细讲解。<BR><BR>3.5
编译指令<BR><BR> 以`(反引号)开始的某些标识符是编译器指令。在Verilog
语言编译时,特定的编译器指令在整个编译过程中有效(编译过程可跨越多个文件),直到遇到其它的不同编译程序指令。完整的标准编译器指令如下:<BR><BR>*
`define, `undef<BR>* `ifdef, `else, `endif<BR>*
`default_nettype<BR>* `include<BR>* `resetall<BR>* `timescale<BR>*
`unconnected_drive, `nounconnected_drive<BR>* `celldefine,
`endcelldefine<BR><BR>3.5.1 `define
和`undef<BR><BR> `define指令用于文本替换,它很像C语言中的#define
指令,如:<BR><BR>`define MAX_BUS_SIZE 32<BR>. . . <BR>reg [
`MAX_BUS_SIZE - 1:0 ] AddReg;<BR><BR>一旦`define
指令被编译,其在整个编译过程中都有效。例如,通过另一个文件中的`define指令,MAX_BUS_SIZE
能被多个文件使用。<BR>`undef 指令取消前面定义的宏。例如:<BR><BR>`define WORD 16
//建立一个文本宏替代。<BR>. . .<BR>wire [ `WORD : 1] Bus;<BR>. . . <BR>`undef
WORD<BR>// 在`undef编译指令后, WORD的宏定义不再有效. <BR><BR>3.5.2 `ifdef、`else
和`endif<BR><BR> 这些编译指令用于条件编译,如下所示:<BR><BR>`ifdef
WINDOWS<BR>parameter WORD_SIZE = 16<BR>`else<BR>parameter WORD_SIZE
=
32<BR>`endif<BR><BR> 在编译过程中,如果已定义了名字为WINDOWS的文本宏,就选择第一种参数声明,否则选择第二种参数说明。<BR> `else
程序指令对于`ifdef 指令是可选的。<BR><BR>3.5.3
`default_nettype<BR><BR> 该指令用于为隐式线网指定线网类型。也就是将那些没有被说明的连线定义线网类型。<BR><BR>`default_nettype
wand<BR><BR> 该实例定义的缺省的线网为线与类型。因此,如果在此指令后面的任何模块中没有说明的连线,那么该线网被假定为线与类型。<BR><BR>3.5.4
`include<BR><BR> `include
编译器指令用于嵌入内嵌文件的内容。文件既可以用相对路径名定义,也可以用全路径名定义, 例如:<BR><BR>`include " . .
/ . . /primitives.v"<BR><BR> 编译时,这一行由文件“../../primitives.v”
的内容替代。<BR><BR>3.5.5 `resetall
<BR><BR> 该编译器指令将所有的编译指令重新设置为缺省值。<BR>`resetall<BR>例如,该指令使得缺省连线类型为线网类型。<BR><BR>3.5.6
`timescale<BR><BR> 在Verilog HDL
模型中,所有时延都用单位时间表述。使用`timescale编译器指令将时间单位与实际时间相关联。该指令用于定义时延的单位和时延精度。`timescale编译器指令格式为:<BR><BR>`timescale
time_unit / time_precision<BR>time_unit 和time_precision
由值1、10、和100以及单位s、ms、us、ns、ps和fs组成。例如:<BR>`timescale
1ns/100ps<BR><BR>表示时延单位为1ns, 时延精度为100ps。`timescale 编译器指令在模块说明外部出现,
并且影响后面所有的时延值。例如:<BR><BR>`timescale 1ns/ 100ps<BR>module AndFunc (Z,
A, B);<BR>output Z;<BR>input A, B;<BR><BR>and # (5.22, 6.17 ) Al (Z,
A,
B);<BR>//规定了上升及下降时延值。<BR>endmodule<BR><BR> 编译器指令定义时延以ns为单位,并且时延精度为1/10
ns(100 ps)。因此,时延值5.22对应5.2 ns, 时延6.17对应6.2
ns。如果用如下的`timescale程序指令代替上例中的编译器指令,<BR><BR>`timescale
10ns/1ns<BR><BR> 那么5.22对应52ns,
6.17对应62ns。<BR> 在编译过程中,`timescale指令影响这一编译器指令后面所有模块中的时延值,直至遇到另一个`timescale指令或`resetall指令。当一个设计中的多个模块带有自身的`timescale编译指令时将发生什么?在这种情况下,模拟器总是定位在所有模块的最小时延精度上,并且所有时延都相应地换算为最小时延精度。例如,<BR><BR>`timescale
1ns/ 100ps<BR>module AndFunc (Z, A, B);<BR>output Z;<BR>input A,
B;<BR><BR>and # (5.22, 6.17 ) Al (Z, A,
B);<BR>endmodule<BR><BR>`timescale 10ns/ 1ns<BR>module TB;<BR>reg
PutA, PutB;<BR>wire GetO;<BR><BR>initial<BR>begin<BR>PutA =
0;<BR>PutB = 0;<BR>#5.21 PutB = 1;<BR>#10.4 PutA = 1;<BR>#15 PutB =
0;<BR>end<BR>AndFunc AF1(GetO, PutA,
PutB);<BR>endmodule<BR><BR> 在这个例子中,每个模块都有自身的`timescale编译器指令。`timescale编译器指令第一次应用于时延。因此,在第一个模块中,5.22对应5.2
ns, 6.17对应6.2 ns; 在第二个模块中5.21对应52 ns, 10.4对应104 ns, 15对应150
ns。如果仿真模块TB,设计中的所有模块最小时间精度为100 ps。因此,所有延迟(特别是模块TB中的延迟)将换算成精度为100
ps。延迟52 ns现在对应520*100 ps,104对应1040*100 ps,150对应1500*100
ps。更重要的是,仿真使用100
ps为时间精度。如果仿真模块AndFunc,由于模块TB不是模块AddFunc的子模块,模块TB中的`timescale程序指令将不再有效。<BR><BR>3.5.7
`unconnected_drive和`nounconnected_drive
<BR><BR> 在模块实例化中,出现在这两个编译器指令间的任何未连接的输入端口或者为正偏电路状态或者为反偏电路状态。<BR><BR>`unconnected_drive
pull1<BR>. .
.<BR>/*在这两个程序指令间的所有未连接的输入端口为正偏电路状态(连接到高电平)*/<BR>`nounconnected_drive<BR><BR>`unconnected_drive
pull0<BR>. .
.<BR>/*在这两个程序指令间的所有未连接的输入端口为反偏电路状态(连接到低电平)*/<BR>`nounconnected_drive<BR><BR>3.5.8
`celldefine 和
`endcelldefine<BR><BR> 这两个程序指令用于将模块标记为单元模块。它们表示包含模块定义,如下例所示。<BR><BR>`celldefine<BR>module
FD1S3AX (D, CK, Z) ;<BR>. . .
<BR>endmodule<BR>`endcelldefine<BR><BR> 某些PLI例程使用单元模块。<BR><BR>3.6
值集合<BR><BR> Verilog HDL有下列四种基本的值:<BR> 1) 0:逻辑0或“假”<BR> 2)
1:逻辑1或“真”<BR> 3) x:未知<BR> 4)
z:高阻<BR> 注意这四种值的解释都内置于语言中。如一个为z的值总是意味着高阻抗,一个为0的值通常是指逻辑0。<BR>在门的输入或一个表达式中的为“z”的值通常解释成“x”。此外,x值和z值都是不分大小写的,也就是说,值0x1z与值0X1Z相同。Verilog
HDL中的常量是由以上这四类基本值组成的。<BR> Verilog HDL中有三类常量:<BR> 1) 整型<BR> 2)
实数型<BR> 3)
字符串型<BR>下划线符号(_)可以随意用在整数或实数中,它们就数量本身没有意义。它们能用来提高易读性;唯一的限制是下划线符号不能用作为首字符。<BR><BR>3.6.1
整型数<BR><BR> 整型数可以按如下两种方式书写:<BR> 1) 简单的十进制数格式<BR> 2)
基数格式<BR><BR>1. 简单的十进制格式<BR>这种形式的整数定义为带有一个可选的 “+”(一元)或
“-”(一元)操作符的数字序列。下面是这种简易十进制形式整数的例子。<BR>32 十进制数32<BR>-15
十进制数-15<BR>这种形式的整数值代表一个有符号的数。负数可使用两种补码形式表示。因此32在5位的二进制形式中为10000,在6位二进制形式中为110001;-15在5位二进制形式中为10001,在6位二进制形式中为110001。<BR><BR>2.
基数表示法<BR>这种形式的整数格式为:<BR>[size ] 'base value<BR>size
定义以位计的常量的位长;base为o或O(表示八进制),b或B(表示二进制),d或D(表示十进制),h或H(表示十六进制)之一;value是基于base的值的数字序列。值x和z以及十六进制中的a到f不区分大小写。<BR>下面是一些具体实例:<BR><BR>5'O37
5位八进制数<BR>4'D2 4位十进制数<BR>4'B1x_01 4位二进制数<BR>7'Hx 7位x(扩展的x),
即xxxxxxx<BR>4'hZ 4位z(扩展的z) , 即zzzz<BR>4'd-4 非法:数值不能为负<BR>8'h 2 A
在位长和字符之间,以及基数和数值之间允许出现空格<BR>3'b001 非法: ` 和基数b之间不允许出现空格<BR>(2+3)'b10
非法:位长不能够为表达式<BR>注意,x(或z)在十六进制值中代表4位x(或z),在八进制中代表3位x(或z),在二进制中代表1位x(或z)。<BR> 基数格式计数形式的数通常为无符号数。这种形式的整型数的长度定义是可选的。如果没有定义一个整数型的长度,数的长度为相应值中定义的位数。下面是两个例子:<BR>'o721
9位八进制数<BR>'hAF
8位十六进制数<BR>如果定义的长度比为常量指定的长度长,通常在左边填0补位。但是如果数最左边一位为x或z,就相应地用x或z在左边补位。例如:<BR>10'b10
左边添0占位, 0000000010<BR>10'bx0x1
左边添x占位,xxxxxxx0x1<BR>如果长度定义得更小,那么最左边的位相应地被截断。例如:<BR>3'b1001_0011与3'b011
相等<BR>5'H0FFF 与5'H1F
相等<BR>?字符在数中可以代替值z在值z被解释为不分大小写的情况下提高可读性(参见第8章)。<BR><BR>3.6.2
实数<BR><BR> 实数可以用下列两种形式定义:<BR> 1)
十进制计数法;例如<BR><BR>2.0<BR>5.678<BR>11572.12<BR>0.1<BR>2.
//非法:小数点两侧必须有1位数字<BR><BR> 2) 科学计数法; 这种形式的实数举例如下:<BR><BR>23_5.1e2
其值为23510.0; 忽略下划线<BR>3.6E2 360.0 (e与E相同)<BR>5E-4
0.0005<BR><BR> Verilog语言定义了实数如何隐式地转换为整数。实数通过四舍五入被转换为最相近的整数。<BR><BR>42.446,
42.45 转换为整数42<BR>92.5, 92.699 转换为整数93<BR>-15.62 转换为整数-16<BR>-26.22
转换为整数-26<BR><BR>3.6.3
字符串<BR><BR> 字符串是双引号内的字符序列。字符串不能分成多行书写。例如:<BR><BR>"INTERNAL
ERROR"<BR>"REACHED->HERE"<BR><BR>用8位ASCII值表示的字符可看作是无符号整数。因此字符串是8位ASCII值的序列。为存储字符串“INTERNAL
ERROR”,变量需要8*14位。<BR><BR>reg [1 : 8*14] Message;<BR>. . .
<BR>Message = "INTERNAL ERROR"<BR>反斜线 (\ ) 用于对确定的特殊字符转义。<BR>\n
换行符<BR>\t 制表符<BR>\\ 字符\本身<BR>\" 字符"<BR>\206 八进制数206对应的字符<BR><BR>3.7
数据类型<BR><BR> Verilog HDL 有两大类数据类型。<BR> 1) 线网类型。net type
表示Verilog结构化元件间的物理连线。它的值由驱动元件的值决定,例如连续赋值或门的输出。如果没有驱动元件连接到线网,线网的缺省值为z。<BR> 2)
寄存器类型。register
type表示一个抽象的数据存储单元,它只能在always语句和initial语句中被赋值,并且它的值从一个赋值到另一个赋值被保存下来。寄存器类型的变量具有x
的缺省值。<BR><BR>3.7.1 线网类型<BR><BR> 线网数据类型包含下述不同种类的线网子类型。<BR><BR>* wire
<BR>* tri <BR>* wor <BR>* trior <BR>* wand <BR>* triand <BR>* trireg
<BR>* tri1 <BR>* tri0<BR>* supply0 <BR>* supply1
<BR><BR>简单的线网类型说明语法为:<BR><BR>net_kind [msb:lsb] net1, net2, . . . ,
netN;<BR><BR>net_kind 是上述线网类型的一种。msb和lsb
是用于定义线网范围的常量表达式;范围定义是可选的;如果没有定义范围,缺省的线网类型为1位。下面是线网类型说明实例。<BR><BR>wire
Rdy, Start; //2个1位的连线。<BR>wand [2:0] Addr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -