第3章 Verilog HDL的基本语法(2)

2019-04-13 21:10

第三章 Verilog HDL 基本语法

--------------------------------------------------------------------------------------------------------------------------------------------------

当常量不说明位数时,默认值是32位,每个字母用8位的ASCII值表示。 例:

10=32?d10=32?b1010 1=32?d1=32?b1

-1=-32?d1=32?hFFFFFFFF ?BX=32?BX=32?BXXXXXXX…X “AB”=16?B01000001_01000010

二.参数(Parameter)型

在Verilog HDL中用parameter来定义常量,即用parameter来定义一个标识符代表一个常量,称为符号常量,即标识符形式的常量,采用标识符代表一个常量可提高程序的可读性和可维护性。parameter型数据是一种常数型的数据,其说明格式如下:

parameter 参数名1=表达式,参数名2=表达式, …, 参数名n=表达式;

parameter是参数型数据的确认符,确认符后跟着一个用逗号分隔开的赋值语句表。在每一个赋值语句的右边必须是一个常数表达式。也就是说,该表达式只能包含数字或先前已定义过的参数。见下列:

parameter msb=7; //定义参数msb为常量7 parameter e=25, f=29; //定义二个常数参数 parameter r=5.7; //声明r为一个实型参数

parameter byte_size=8, byte_msb=byte_size-1; //用常数表达式赋值 parameter average_delay = (r+f)/2; //用常数表达式赋值

参数型常数经常用于定义延迟时间和变量宽度。在模块或实例引用时可通过参数传递改变在被引用模块或实例中已定义的参数。下面将通过两个例子进一步说明在层次调用的电路中改变参数常用的一些用法。

[例1]:在引用Decode实例时,D1,D2的Width将采用不同的值4和5,且D1的Polarity将为0。可用例子中所用的方法来改变参数,即用 #(4,0)向D1中传递 Width=4,Polarity=0; 用#(5)向D2中传递Width=5,Polarity仍为1。

module Decode(A,F);

parameter Width=1, Polarity=1; …………… endmodule module Top; wire[3:0] A4; wire[4:0] A5; wire[15:0] F16; wire[31:0] F32;

Decode #(4,0) D1(A4,F16); Decode #(5) D2(A5,F32); Endmodule

[例2]:下面是一个多层次模块构成的电路,在一个模块中改变另一个模块的参数时,需要使用defparam命令

22

第三章 Verilog HDL 基本语法

--------------------------------------------------------------------------------------------------------------------------------------------------

Module Test; wire W; Top T ( );emdmodulemodule Top; wire W Block B1 ( ); Block B2 ( );endmodulemodule Block; Parameter P = 0;endmodulemodule Annotate; defparam Test.T.B1.P = 2, Test.T.B2.P = 3;endmoduleAnnoteTest TTopB1BlockB2Block

3.2.2 变量

变量即在程序运行过程中其值可以改变的量,在Verilog HDL中变量的数据类型有很多种,这里只对常用的几种进行介绍。

网络数据类型表示结构实体(例如门)之间的物理连接。网络类型的变量不能储存值,而且它必需受到驱动器(例如门或连续赋值语句,assign)的驱动。如果没有驱动器连接到网络类型的变量上,则该变量就是高阻的,即其值为z。常用的网络数据类型包括wire型和tri型。这两种变量都是用于连接器件单元,它们具有相同的语法格式和功能。之所以提供这两种名字来表达相同的概念是为了与模型中所使用的变量的实际情况相一致。wire型变量通常是用来表示单个门驱动或连续赋值语句驱动的网络型数据,tri型变量则用来表示多驱动器驱动的网络型数据。如果wire型或tri型变量没有定义逻辑强度(logic strength),在多驱动源的情况下,逻辑值会发生冲突从而产生不确定值。下表为wire型和tri型变量的真值表(注意:这里假设两个驱动源的强度是一致的,关于逻辑强度建模请参阅附录:Verilog语言参考书)。

wire/tri 0 1 x z 0 0 x x 0 1 x 1 x 1 x x x x x z 0 1 x z

一. wire型

23

第三章 Verilog HDL 基本语法

--------------------------------------------------------------------------------------------------------------------------------------------------

wire型数据常用来表示用于以assign关键字指定的组合逻辑信号。Verilog程序模块中输入输出信号类型缺省时自动定义为wire型。wire型信号可以用作任何方程式的输入,也可以用作“assign”语句或实例元件的输出。

wire型信号的格式同reg型信号的很类似。其格式如下:

wire [n-1:0] 数据名1,数据名2,…数据名i; //共有i条总线,每条总线内有n条线路 或

wire [n:1] 数据名1,数据名2,…数据名i;

wire是wire型数据的确认符,[n-1:0]和[n:1]代表该数据的位宽,即该数据有几位。最后跟着的是数据的名字。如果一次定义多个数据,数据名之间用逗号隔开。声明语句的最后要用分号表示语句结束。看下面的几个例子。

wire a; //定义了一个一位的wire型数据 wire [7:0] b; //定义了一个八位的wire型数据 wire [4:1] c, d; //定义了二个四位的wire型数据

二. reg型

寄存器是数据储存单元的抽象。寄存器数据类型的关键字是reg.通过赋值语句可以改变寄存器储存的值,其作用与改变触发器储存的值相当。Verilog HDL语言提供了功能强大的结构语句使设计者能有效地控制是否执行这些赋值语句。这些控制结构用来描述硬件触发条件,例如时钟的上升沿和多路器的选通信号。在行为模块介绍这一节中我们还要详细地介绍这些控制结构。reg类型数据的缺省初始值为不定值,x。

reg型数据常用来表示用于“always”模块内的指定信号,常代表触发器。通常,在设计中要由“always”块通过使用行为描述语句来表达逻辑关系。在“always”块内被赋值的每一个信号都必须定义成reg型。

reg型数据的格式如下:

reg [n-1:0] 数据名1,数据名2,… 数据名i; 或

reg [n:1] 数据名1,数据名2,… 数据名i;

reg是reg型数据的确认标识符,[n-1:0]和[n:1]代表该数据的位宽,即该数据有几位(bit)。最后跟着的是数据的名字。如果一次定义多个数据,数据名之间用逗号隔开。声明语句的最后要用分号表示语句结束。看下面的几个例子:

reg rega; //定义了一个一位的名为rega的reg型数据 reg [3:0] regb; //定义了一个四位的名为regb的reg型数据

reg [4:1] regc, regd; //定义了两个四位的名为regc和regd的reg型数据

对于reg型数据,其赋值语句的作用就象改变一组触发器的存储单元的值。在Verilog中有许多构造(construct)用来控制何时或是否执行这些赋值语句。这些控制构造可用来描述硬件触发器的各种具体情况,如触发条件用时钟的上升沿等,或用来描述具体判断逻辑的细节,如各种多路选择器。reg型数据的缺省初始值是不定值。reg型数据可以赋正值,也可以赋负值。但当一个reg型数据是一个表达式中的操作数时,它的值被当作是无符号值,即正值。例如:当一个四位的寄存器用作表达式中的操作数时,如果开始寄存器被赋以值-1,则在表达式中进行运算时,其值被认为是+15。

注意:

24

第三章 Verilog HDL 基本语法

--------------------------------------------------------------------------------------------------------------------------------------------------

reg型只表示被定义的信号将用在“always”块内,理解这一点很重要。并不是说reg型信号一定是寄存器或触发器的输出。虽然reg型信号常常是寄存器或触发器的输出,但并不一定总是这样。在本书中我们还会对这一点作更详细的解释。

三. memory型

Verilog HDL通过对reg型变量建立数组来对存储器建模,可以描述RAM型存储器,ROM存储器和reg文件。数组中的每一个单元通过一个数组索引进行寻址。在Verilog语言中没有多维数组存在。 memory型数据是通过扩展reg型数据的地址范围来生成的。其格式如下:

reg [n-1:0] 存储器名[m-1:0]; 或 reg [n-1:0] 存储器名[m:1];

在这里,reg[n-1:0]定义了存储器中每一个存储单元的大小,即该存储单元是一个n位的寄存器。存储器名后的[m-1:0]或[m:1]则定义了该存储器中有多少个这样的寄存器。最后用分号结束定义语句。下面举例说明:

reg [7:0] mema[255:0];

这个例子定义了一个名为mema的存储器,该存储器有256个8位的存储器。该存储器的地址范围是0到255。注意:对存储器进行地址索引的表达式必须是常数表达式。

另外,在同一个数据类型声明语句里,可以同时定义存储器型数据和reg型数据。见下例:

parameter wordsize=16, //定义二个参数。

memsize=256;

reg [wordsize-1:0] mem[memsize-1:0],writereg, readreg;

尽管memory型数据和reg型数据的定义格式很相似,但要注意其不同之处。如一个由n个1位寄存器构成的存储器组是不同于一个n位的寄存器的。见下例:

reg [n-1:0] rega; //一个n位的寄存器

reg mema [n-1:0]; //一个由n个1位寄存器构成的存储器组

一个n位的寄存器可以在一条赋值语句里进行赋值,而一个完整的存储器则不行。见下例:

rega =0; //合法赋值语句 mema =0; //非法赋值语句

如果想对memory中的存储单元进行读写操作,必须指定该单元在存储器中的地址。下面的写法是正确的。

mema[3]=0; //给memory中的第3个存储单元赋值为0。

进行寻址的地址索引可以是表达式,这样就可以对存储器中的不同单元进行操作。表达式的值可以取决于电路中其它的寄存器的值。例如可以用一个加法计数器来做RAM的地址索引。本小节里只对以上几种常用的数据类型和常数进行了介绍,其余的在以后的章节的示例中用到之处再逐一介绍。有兴趣的同学可以参阅附录:Verilog语言参考书

3.3. 运算符及表达式

Verilog HDL语言的运算符范围很广,其运算符按其功能可分为以下几类:

25

第三章 Verilog HDL 基本语法

--------------------------------------------------------------------------------------------------------------------------------------------------

1) 2) 3) 4) 5) 6) 7) 8) 9) 算术运算符(+,-,×,/,%) 赋值运算符(=,<=)

关系运算符(>,<,>=,<=) 逻辑运算符(&&,||,!) 条件运算符(?:)

位运算符(~,|,^,&,^~) 移位运算符(<<,>>) 拼接运算符({ }) 其它

在Verilog HDL语言中运算符所带的操作数是不同的,按其所带操作数的个数运算符可分为三种:

1) 单目运算符(unary operator):可以带一个操作数,操作数放在运算符的右边。 2) 二目运算符(binary operator):可以带二个操作数,操作数放在运算符的两边。

3) 三目运算符(ternary operator):可以带三个操作,这三个操作数用三目运算符分隔

开。 见下例:

clock = ~clock; // ~是一个单目取反运算符, clock是操作数。 c = a | b; // 是一个二目按位或运算符, a 和 b是操作数。 r = s ? t : u; // ?: 是一个三目条件运算符, s,t,u是操作数。

下面对常用的几种运算符进行介绍。

3.3.1.基本的算术运算符

在Verilog HDL语言中,算术运算符又称为二进制运算符,共有下面几种: 1) + (加法运算符,或正值运算符,如 rega+regb,+3) 2) - (减法运算符,或负值运算符,如 rega-3,-3) 3) × (乘法运算符,如rega*3) 4) / (除法运算符,如5/3)

5) % (模运算符,或称为求余运算符,要求%两侧均为整型数据。如7%3的值为1)

在进行整数除法运算时,结果值要略去小数部分,只取整数部分。而进行取模运算时,结果值的符号位采用模运算式里第一个操作数的符号位。见下例。

模运算表达式 结果 说明 10%3 1 余数为1 11%3 2 余数为2 12%3 0 余数为0即无余数 -10%3 -1 结果取第一个操作数的符号位,所以余数为-1 11%3 2 结果取第一个操作数的符号位,所以余数为2.

注意: 在进行算术运算操作时,如果某一个操作数有不确定的值x,则整个结果也为不定值x。

3.3.2.位运算符

Verilog HDL作为一种硬件描述语言,是针对硬件电路而言的。在硬件电路中信号有四种状态值1,0,x,z.在电路中信号进行与或非时,反映在Verilog HDL中则是相应的操作数的位运算。Verilog HDL提供了以下五种位运算符:

1) ~ //取反 2) & //按位与 3) | //按位或 4) ^ //按位异或

26


第3章 Verilog HDL的基本语法(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:全国小学三年级数学竞赛试题

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: