VerilogHDL基础之:数据类型和运算符

其他数据类型在后面的章节里逐步介绍,读者也可以查阅附录中VerilogHDL语法参考书的有关章节逐步掌握。其他的类型如下:large型、medium型、scalared型、time型、small型、tri型、trio型、tri1型、triand型、trior型、trireg型、vectored型、wand型和wor型。

常量是在程序运行过程中其值不能被改变的量。下面首先对在VerilogHDL语言中使用的数字及其表示方式进行介绍。

(1)整数。

在VerilogHDL中,整型常量有以下4种进制表示形式。

①二进制整数(b或B)。

②十进制整数(d或D)。

③十六进制整数(h或H)。

④八进制整数(o或O)。

数字表达方式有以下3种。

①<位宽><进制><数字>,这是一种全面的描述方式。

②<进制><数字>,在这种描述方式中,数字的位宽采用缺省位宽(这由具体的机器系统决定,但至少32位)。

③<数字>,在这种描述方式中,采用缺省进制十进制。

在表达式中,位宽指明了数字的精确位数。例如:一个4位二进制数数字的位宽为4,一个4位十六进制数数字的位宽为16(因为每单个十六进制数要用4位二进制数来表示),如下例所示:

(2)x和z值。

在数字电路中,x代表不定值,z代表高阻值。一个x可以用来定义十六/八/二进制数的四/三/一位二进制数的状态。z的表示方式同x类似。z还有一种表达方式是可以写作。在使用case表达式时建议使用这种写法,以提高程序的可读性,如下例所示:

(3)负数。

一个数字可以被定义为负数,只需在位宽表达式前加一个减号,并且减号必须写在数字定义表达式的最前面。注意减号不可以放在位宽和进制之间,也不可以放在进制和具体的数之间,如下例所示:

(4)下划线(underscore_)。

下划线可以用来分隔数字的表达以提高程序可读性。但不可以用在位宽和进制处,只能用在具体的数字之间,例如:

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

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

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

parametermsb=7;//定义参数msb为常量7

parametere=25,f=29;//定义两个常数参数

parameterbyte_size=8,byte_msb=byte_size-1;//用常数表达式赋值

parameteraverage_delay=(r+f)/2;//用常数表达式赋值

……………

endmodule

moduleTop;

wire[4:0]A5;

wire[15:0]F16;

wire[31:0]F32;

Decode#(4,0)D1(A4,F16);//模块引用,并传递参数(4,0)

Decode#(5)D2(A5,F32);//模块引用,并传递参数(5)

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

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

wire型变量通常是用来表示单个门驱动或连续赋值语句驱动的网络型数据,tri型变量则用来表示多驱动器驱动的网络型数据。如果wire型或tri型变量没有定义逻辑强度(logicstrength),在多驱动源的情况下,逻辑值会发生冲突,从而产生不确定值。

表1所示为在同等驱动强度下,两个驱动源驱动的wire型和tri型变量的真值表。

表1wire/tri型变量真值表

wire/tri型变量双驱动源运算结果

驱动源1

驱动源2

0

1

x

z

也可以如下表示:

wire[n:1]变量名1,变量名2,…,变量名i;//共有i条总线,每条总线内有n条线路

wirea;//定义了一个一位的wire型变量

wire[7:0]b;//定义了一个八位的wire型变量

wire[4:1]c,d;//定义了两个四位的wire型变量

reg[n-1:0]变量名1,变量名2,…,变量名i;//共有i条总线,每条总线内有n条线路

reg[n:1]变量名1,变量名2,…,变量名i;//共有i条总线,每条总线内有n条线路

regrega;//定义了一个一位的名为rega的reg型变量

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

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

reg型变量可以赋正值,也可以赋负值。但当一个reg型变量是一个表达式中的操作数时,它的值将被当作是无符号值,即正值。例如:当一个四位的寄存器用作表达式中的操作数时,如果开始寄存器被赋以值-1,则在表达式中进行运算时,其值被认为是+15。

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。需要注意的是,对存储器进行地址索引的表达式必须是常数表达式。

parameterwordsize=16,memsize=256;//定义两个参数

reg[wordsize-1:0]mem[memsize-1:0],writereg,readreg;//使用可变参数来定义存储器

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

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

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

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

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

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

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

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

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

在VerilogHDL语言中运算符所带的操作数是不同的,按其所带操作数的个数运算符可分为以下3种。

单目运算符(unaryoperator):可以带一个操作数,操作数放在运算符的右边。

二目运算符(binaryoperator):可以带两个操作数,操作数放在运算符的两边。

三目运算符(ternaryoperator):可以带三个操作数,这三个操作数用三目运算符分隔开。

例如:

clock=~clock;//~是一个单目取反运算符,clock是操作数。

c=a|b;//|是一个二目按位或运算符,a和b是操作数。

r=st:u;//:是一个三目条件运算符,s,t,u是操作数。

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

在VerilogHDL语言中,算术运算符又称为二进制运算符,共有下面几种。

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

10%31//余数为1

11%32//余数为2

12%30//余数为0,即无余数

-10%3-1//结果取第一个操作数的符号位,所以余数为-1

11%32//结果取第一个操作数的符号位,所以余数为2.

注意

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

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

说明:

下面对各运算符分别进行介绍。

“取反”运算符~

~是一个单目运算符,用来对一个操作数进行按位取反运算。如表2所示为单目运算符~的运算规则表。

表2~运算规则表

~运算

操作数

结果

举例说明:

“按位与”运算符&

按位与运算就是将两个操作数的相应位进行与运算,其运算规则如表3所示。

表3&运算规则表

&运算

操作数1

操作数2

“按位或”运算符|

按位或运算就是将两个操作数的相应位进行或运算,其运算规则如表4所示。

表4|运算规则表

|运算

“按位异或”运算符^(也称之为XOR运算符)

按位异或运算就是将两个操作数的相应位进行异或运算,其运算规则如表5所示。

表5^运算规则表

^运算

“按位同或”运算符^~

按位同或运算就是将两个操作数的相应位先进行异或运算再进行非运算,其运算规则如表6所示。

表6^~运算规则表

^~运算

不同长度的数据进行位运算

两个长度不同的数据进行位运算时,系统会自动将两者按右端对齐。位数少的操作数会在相应的高位用0填满,以使两个操作数按位进行操作。

在VerilogHDL语言中存在3种逻辑运算符。

“&&”和“||”是二目运算符,它要求有两个操作数,如(a>b)&&(b>c),(ab)。如表7所示为逻辑运算的真值表。它表示当a和b的值为不同的组合时,各种逻辑运算所得到的值。

表7逻辑运算真值表

逻辑运算及结果

a

b

!a

!b

a&&b

a||b

逻辑运算符中“&&”和“||”的优先级别低于关系运算符,“!”的优先级别高于算术运算符,例如。

(a>b)&&(x>y)可写成:a>b&&x>y

(a==b)||(x==y)可写成:a==b||x==y

(!a)||(a>b)可写成:!a||a>b

为了提高程序的可读性,明确表达各运算符间的优先关系,建议使用括号。

关系运算符共有以下4种。

所有的关系运算符有着相同的优先级别。关系运算符的优先级别低于算术运算符的优先级别,例如。

a

a<(size-1)

size-(1

size-1

从上面的例子可以看出这两种不同运算符的优先级别。当表达式size-(1

在VerilogHDL语言中存在4种等式运算符。

这4个运算符都是二目运算符,它要求有两个操作数。“==”和“!=”又称为逻辑等式运算符,其结果由两个操作数的值决定。由于操作数中某些位可能是不定值x和高阻值z,结果可能为不定值x。

“===”和“!==”运算符则不同,它在对操作数进行比较时,对某些位的不定值x和高阻值z也进行比较。两个操作数必需完全一致,其结果才是1,否则为0。“===”和“!==”运算符常用于case表达式的判别,所以又称为“case等式运算符”。

这4个等式运算符的优先级别是相同的。下面画出“==”与“===”的真值表,帮助理解两者间的区别。

表8等式运算符真值表

===运算

==运算

下面举一个例子说明“==”与“===”的区别。

if(A==1’bx)$display("AisX");//当A等于X时,这个语句不执行

if(A===1’bx)$display("AisX");//当A等于X时,这个语句执行

在VerilogHDL中有两种移位运算符。

<<:(左移位运算符)

>>:(右移位运算符)

其使用方法如下:

a>>n;

a<

a代表要进行移位的操作数,n代表要移几位。这两种移位运算都用0来填补移出的空位。下面举例说明:

moduleshift;

reg[3:0]start,result;

initialbegin

start=1;//start在初始时刻设为值0001

result=(start<<2);//移位后,start的值0100,然后赋给result

end

从上面的例子可以看出,start在移过两位以后,用0来填补空出的位。进行移位运算时应注意移位前后变量的位数,下面举例说明。

4’b1001<<1=5’b10010;//左移1位后用0填补低位

4’b1001<<2=6’b100100;//左移2位后用00填补低位

1<<6=32’b1000000;//左移6位后用000000填补低位

4’b1001>>1=4’b0100;//右移1位后,低1位丢失,高1位用0填补

4’b1001>>4=4’b0000;//右移4位后,低4位丢失,高4位用0填补

在VerilogHDL语言有一个特殊的运算符:位拼接运算符{}。用这个运算符可以把两个或多个信号的某些位拼接起来进行运算操作。其使用方法如下:

{信号1的某几位,信号2的某几位,..,..,信号n的某几位}

即把某些信号的某些位详细地列出来,中间用逗号分开,最后用大括号括起来表示一个整体信号,例如:

{a,b[3:0],w,3’b101}

也可以写成为:

{a,b[3],b[2],b[1],b[0],w,1’b1,1’b0,1’b1}

在位拼接表达式中不允许存在没有指明位数的信号。这是因为在计算拼接信号的位宽的大小时必需知道其中每个信号的位宽。

位拼接也可以用重复法来简化表达式,如下所示:

{4{w}}//等同于{w,w,w,w}

位拼接还可以用嵌套的方式来表达,如下所示:

{b,{3{a,b}}}//等同于{b,a,b,a,b,a,b}

用于表示重复的表达式必须是常数表达式,如上例中的4和3。

缩减运算符是单目运算符,也有与、或、非运算。其与、或、非运算规则类似于位运算符的与、或、非运算规则,但其运算过程不同。位运算是对操作数的相应位进行与、或、非运算,操作数是几位数,则运算结果也是几位数。而缩减运算则不同,缩减运算是对单个操作数进行与、或、非递推运算,最后的运算结果是一位的二进制数。

缩减运算的具体运算过程如下。

(1)先将操作数的第一位与第二位进行与、或、非运算。

(2)将运算结果与第三位进行与、或、非运算,依次类推,直至最后一位。

reg[3:0]B;

regC;

C=&B;

相当于:

C=((B[0]&B[1])&B[2])&B[3];

由于缩减运算的与、或、非运算规则类似于位运算符与、或、非运算规则,这里不再详细讲述,可参照位运算符的运算规则介绍。

THE END
1.什么是算术运算?什么是关系运算?什么是逻辑运算?题目 什么是算术运算?什么是关系运算?什么是逻辑运算? 相关知识点: 试题来源: 解析1.算术运算:用于各类数值运算.包括加(+)、减(-)、乘(*)、除(/)、求余(或称模运算,%)、自增(++)、自减(--)共七种.2.关系运算:用于比较运算.包括大于(>)、小于(=)、小于等于(>=,https://easylearn.baidu.com/edu-page/tiangong/questiondetail?id=1726076010199297025&fr=search
2.C语言运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C语言提供了如下类型的运算符:算符运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 杂项运算符6.1 算术运算符假设A为10,B为20。运算符描述实例 + 把两个操作数相加 A + B将得到30 - 从第一个操作数中减去第二个操作数 A - B将得到-10 * 把https://www.jianshu.com/p/c604515b6bb2
3.计算机底层知识之二进制像图形模式,将数值处理为单纯的0和1的罗列就是逻辑 计算机能处理的运算,大体可分为算术运算和逻辑运算。 算术运算是指加减乘除四则运算 逻辑运算是指对二进制数各数字位的0和1分别进行处理的运算 逻辑非(NOT运算) 逻辑与(AND运算) 逻辑或(OR运行) https://developer.aliyun.com/article/1195911
4.c语言例题第五章 5.1 什么是算术运算?什么是关系运算?什么是逻辑运算? 解:略。 5.2 C语言中如何表示“真”和“假”?系统如何判断一个量的“真”和“假”? 解:设有一个逻辑表达式,若其结果为“真”,则以1表示;若其结果为“假”,则以0表示。但是判断一个逻辑量的值时,以0代表“真”,以非0代表“假”。例https://www.360doc.cn/article.aspx?id=20848770
5.计算机的逻辑运算和算术的逻辑运算的主要区别是什么呢?爱问知识人逻辑运算中,1+1=1;在算术运算中1+1=10。所以在逻辑运算中,跟”或“运算有关的,跟算术运算都https://iask.sina.com.cn/b/1SWRjJftuNOb.html
6.python关系运算符python关系运算符号包括哪些一、运算符是什么? 运算符是用于数学计算,比较大小和逻辑运算的符号。python中主要有以下几类运算符: 算术运算符 比较(关系)运算符 赋值运算符 逻辑运算符 位运算符 成员运算符 身份运算符 二、算数运算符 算数运算符主要用于数学运算,部分运算符也可以用于其他数据类型的运算。 https://blog.51cto.com/u_16213725/8561021
7.C语言课堂教学案例6篇(全文)C语言运算符可以分为:算术运算符、逻辑运算符、关系运算符、位运算符、赋值运算符。2.6.1 算术运算符和算术表达式 1.算术运算符:加、减、乘、除及取模即:+,-,*,/,%来表示。C语言规定: (1)模运算符%,仅用于整型变量或整型常量。 (2)优先级:一个表达式中如有多个运算符,则计算先后次序为相应运算符的优https://www.99xueshu.com/w/file76v5wc0w.html
8.003C++基本运算信奥赛之路1C++语法基础【信奥赛之路 1】-- C++语法基础 作者:小凡学编程003_C++基本运算算术运算和赋值运算 算术运算 C++运算符包括算术运算符、关系运算符、逻辑运算符、位操作运算符等等 其中算术运算符用于各类数值运算。包括加(+)、减(-)、乘(*)、除(/)、求余(或称模运算,%)、共5种 注意: /、%后面不能为0 %两边必须都https://download.csdn.net/blog/column/12425970/132585333
9.C语言基础知识笔记1※ 关系运算符 ※ 逻辑运算符 ※ 三目运算符 2、算术运算符 C语言基本算术运算符如下表: 除法运算中注意: 如果相除的两个数都是整数的话,则结果也为整数,小数部分省略,如8/3 = 2;而两数中有一个为小数,结果则为小数,如:9.0/2 = 4.500000。 https://www.imooc.com/article/23511