Verilog HDL基础教程之:数据类型和运算符
2.寄存器型变量
寄存器是数据储存单元的抽象。寄存器型变量的关键字是reg。通过赋值语句可以改变寄存器储存的值,其作用与改变触发器储存的值相当。
Verilog HDL语言提供了功能强大的结构语句使设计者能有效地控制是否执行这些赋值语句。这些控制结构用来描述硬件触发条件,例如时钟的上升沿和多路器的选通信号。reg类型变量的缺省初始值为不定值,即x。
reg型变量常用来表示用于“always”模块内的指定信号,常代表触发器。通常,在设计中要由“always”块通过使用行为描述语句来表达逻辑关系。在“always”块内被赋值的每一个信号都必须定义成reg型。和wire型变量类似,reg型变量的声明格式如下:
reg [n-1:0] 变量名1,变量名2,…,变量名i; //共有i条总线,每条总线内有n条线路
也可以如下表示:
reg [n:1] 变量名1,变量名2,…,变量名i; //共有i条总线,每条总线内有n条线路
其中,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型变量可以赋正值,也可以赋负值。但当一个reg型变量是一个表达式中的操作数时,它的值将被当作是无符号值,即正值。例如:当一个四位的寄存器用作表达式中的操作数时,如果开始寄存器被赋以值-1,则在表达式中进行运算时,其值被认为是+15。
3.存储器型变量
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的存储器
这个例子定义了一个名为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 HDL语言的运算符范围很广,其运算符按其功能可分为以下几类。
算术运算符:(+,-,×,/,%)。
赋值运算符:(=,=)。
关系运算符:(>,,>=,=)。
逻辑运算符:(,||,!)。
条件运算符:(?:)。
位运算符:(~,|,^,,^~)。
移位运算符:(,>>)。
拼接运算符:({ })。
其他
在Verilog HDL语言中运算符所带的操作数是不同的,按其所带操作数的个数运算符可分为以下3种。
单目运算符(unary operator):可以带一个操作数,操作数放在运算符的右边。
二目运算符(binary operator):可以带两个操作数,操作数放在运算符的两边。
三目运算符(ternary operator):可以带三个操作数,这三个操作数用三目运算符分隔开。
例如:
clock = ~clock; // ~ 是一个单目取反运算符,clock是操作数。
c = a | b; // | 是一个二目按位或运算符,a 和 b是操作数。
r = s ? t : u; // ?: 是一个三目条件运算符,s,t,u是操作数。
下面对常用的几种运算符进行介绍。
1.基本的算术运算符
在Verilog HDL语言中,算术运算符又称为二进制运算符,共有下面几种。
+:(加法运算符或正值运算符,如ega+regb、+3)。
−:(减法运算符或负值运算符,如rega−3、−3)。
´:(乘法运算符,如rega´3)。
/:(除法运算符,如5/3)。
% :(模运算符或求余运算符,要求%两侧均为整型数据,如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。 |
评论