VerilogHDL简明教程第4章表达式.docx

上传人:b****1 文档编号:3024691 上传时间:2023-05-05 格式:DOCX 页数:15 大小:21.70KB
下载 相关 举报
VerilogHDL简明教程第4章表达式.docx_第1页
第1页 / 共15页
VerilogHDL简明教程第4章表达式.docx_第2页
第2页 / 共15页
VerilogHDL简明教程第4章表达式.docx_第3页
第3页 / 共15页
VerilogHDL简明教程第4章表达式.docx_第4页
第4页 / 共15页
VerilogHDL简明教程第4章表达式.docx_第5页
第5页 / 共15页
VerilogHDL简明教程第4章表达式.docx_第6页
第6页 / 共15页
VerilogHDL简明教程第4章表达式.docx_第7页
第7页 / 共15页
VerilogHDL简明教程第4章表达式.docx_第8页
第8页 / 共15页
VerilogHDL简明教程第4章表达式.docx_第9页
第9页 / 共15页
VerilogHDL简明教程第4章表达式.docx_第10页
第10页 / 共15页
VerilogHDL简明教程第4章表达式.docx_第11页
第11页 / 共15页
VerilogHDL简明教程第4章表达式.docx_第12页
第12页 / 共15页
VerilogHDL简明教程第4章表达式.docx_第13页
第13页 / 共15页
VerilogHDL简明教程第4章表达式.docx_第14页
第14页 / 共15页
VerilogHDL简明教程第4章表达式.docx_第15页
第15页 / 共15页
亲,该文档总共15页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

VerilogHDL简明教程第4章表达式.docx

《VerilogHDL简明教程第4章表达式.docx》由会员分享,可在线阅读,更多相关《VerilogHDL简明教程第4章表达式.docx(15页珍藏版)》请在冰点文库上搜索。

VerilogHDL简明教程第4章表达式.docx

VerilogHDL简明教程第4章表达式

本章讲述在VerilogHDL中编写表达式的基础。

  表达式由操作数和操作符组成。

表达式可以在出现数值的任何地方使用。

4.1操作数

  操作数可以是以下类型中的一种:

  1)常数

  2)参数

  3)线网

  4)寄存器

  5)位选择

  6)部分选择 

  7)存储器单元

  8)函数调用

4.1.1常数

  前面的章节已讲述了如何书写常量。

下面是一些实例。

256,7//非定长的十进制数。

4'b10_11,8'h0A//定长的整型常量。

'b1,'hFBA//非定长的整数常量。

90.00006//实数型常量。

"BOND"//串常量;每个字符作为8位ASCII值存储。

  表达式中的整数值可被解释为有符号数或无符号数。

如果表达式中是十进制整数,例如,12被解释为有符号数。

如果整数是基数型整数(定长或非定长),那么该整数作为无符号数对待。

下面举例说明。

12是01100的5位向量形式(有符号)

-12是10100的5位向量形式(有符号)

5'b01100是十进制数12(无符号)

5'b10100是十进制数20(无符号)

4'd12是十进制数12(无符号)

  更为重要的是对基数表示或非基数表示的负整数处理方式不同。

非基数表示形式的负整数作为有符号数处理,而基数表示形式的负整数值作为无符号数。

因此-44和-6'o54(十进制的44等于八进制的54)在下例中处理不同。

integerCone;

...

Cone=-44/4

Cone=-6'o54/4;

  注意-44和-6'o54以相同的位模式求值;但是-44作为有符号数处理,而-6'o54作为无符号数处理。

因此第一个字符中Cone的值为-11,而在第二个赋值中Cone的值为1073741813。

4.1.2参数

  前一章中已对参数作了介绍。

参数类似于常量,并且使用参数声明进行说明。

下面是参数说明实例。

parameterLOAD=4'd12,STORE=4'd10;

LOAD和STORE为参数的例子,值分别被声明为12和10。

4.1.3线网

  可在表达式中使用标量线网(1位)和向量线网(多位)。

下面是线网说明实例。

wire[0:

3]Prt;//Prt为4位向量线网。

wireBdq;//Bbq是标量线网。

  线网中的值被解释为无符号数。

在连续赋值语句中,

assignPrt=-3;

Prt被赋于位向量1101,实际上为十进制的13。

在下面的连续赋值中,

assignPrt=4'HA;

Prt被赋于位向量1010,即为十进制的10。

4.1.4寄存器

  标量和向量寄存器可在表达式中使用。

寄存器变量使用寄存器声明进行说明。

例如:

integerTemA,TemB;

reg[1:

5]State;

timeQue[1:

5];

  整型寄存器中的值被解释为有符号的二进制补码数,而reg寄存器或时间寄存器中的值被解释为无符号数。

实数和实数时间类型寄存器中的值被解释为有符号浮点数。

TemA=-10;//TemA值为位向量10110,是10的二进制补码。

TemA='b1011;//TemA值为十进制数11。

State=-10;//State值为位向量10110,即十进制数22。

State='b1011;//State值为位向量01011,是十进制值11。

4.1.5位选择

  位选择从向量中抽取特定的位。

形式如下:

net_or_reg_vector[bit_select_expr]

  下面是表达式中应用位选择的例子。

State[1]&&State[4]//寄存器位选择。

Prt[0]|Bbq//线网位选择。

  如果选择表达式的值为x、z,或越界,则位选择的值为x。

例如State[x]值为x。

4.1.6部分选择

  在部分选择中,向量的连续序列被选择。

形式如下:

net_or_reg_vector[msb_const_expr:

1sb_const_expr]

  其中范围表达式必须为常数表达式。

例如。

State[1:

4]//寄存器部分选择。

Prt[1:

3]//线网部分选择。

选择范围越界或为x、z时,部分选择的值为x。

4.1.7存储器单元

  存储器单元从存储器中选择一个字。

形式如下:

memory[word_address]

例如:

reg[1:

8]Ack,Dram[0:

63];

... 

Ack=Dram[60];//存储器的第60个单元。

  不允许对存储器变量值部分选择或位选择。

例如,

Dram[60][2]不允许。

Dram[60][2:

4]也不允许。

  在存储器中读取一个位或部分选择一个字的方法如下:

将存储器单元赋值给寄存器变量,然后对该寄存器变量采用部分选择或位选择操作。

例如,Ack[2]和Ack[2:

4]是合法的表达式。

4.1.8函数调用

  表达式中可使用函数调用。

函数调用可以是系统函数调用(以$字符开始)或用户定义的函数调用。

例如:

$time+SumOfEvents(A,B)

/*$time是系统函数,并且SumOfEvents是在别处定义的用户自定义函数。

*/

4.2操作符

  VerilogHDL中的操作符可以分为下述类型:

  1)算术操作符

  2)关系操作符

  3)相等操作符

  4)逻辑操作符

  5)按位操作符

  6)归约操作符

  7)移位操作符

  8)条件操作符

  9)连接和复制操作符

  下表显示了所有操作符的优先级和名称。

操作符从最高优先级(顶行)到最低优先级(底行)排列。

同一行中的操作符优先级相同。

  除条件操作符从右向左关联外,其余所有操作符自左向右关联。

下面的表达式:

A+B-C

等价于:

(A+B)-C//自左向右

而表达式:

A?

B:

C?

D:

F

等价于:

A?

B:

(C?

D:

F)//从右向左

圆扩号能够用于改变优先级的顺序,如以下表达式:

(A?

B:

C)?

D:

F

4.2.1算术操作符

  算术操作符有:

*+(一元加和二元加)

*-(一元减和二元减)

**(乘)

*/(除)

*%(取模)

  整数除法截断任何小数部分。

例如:

7/4结果为1

取模操作符求出与第一个操作符符号相同的余数。

7%4结果为3

而:

-7%4结果为-3

  如果算术操作符中的任意操作数是X或Z,那么整个结果为X。

例如:

'b10x1+'b01111结果为不确定数'bxxxxx

1.算术操作结果的长度

  算术表达式结果的长度由最长的操作数决定。

在赋值语句下,算术操作结果的长度由操作符左端目标长度决定。

考虑如下实例:

reg[0:

3]Arc,Bar,Crt;

reg[0:

5]Frx;

... 

Arc=Bar+Crt;

Frx=Bar+Crt;

  第一个加的结果长度由Bar,Crt和Arc长度决定,长度为4位。

第二个加法操作的长度同样由Frx的长度决定(Frx、Bat和Crt中的最长长度),长度为6位。

在第一个赋值中,加法操作的溢出部分被丢弃;而在第二个赋值中,任何溢出的位存储在结果位Frx[1]中。

  在较大的表达式中,中间结果的长度如何确定?

在VerilogHDL中定义了如下规则:

表达式中的所有中间结果应取最大操作数的长度(赋值时,此规则也包括左端目标)。

考虑另一个实例:

wire[4:

1]Box,Drt;

wire[1:

5]Cfg;

wire[1:

6]Peg;

wire[1:

8]Adt;

...

assignAdt=(Box+Cfg)+(Drt+Peg);

  表达式左端的操作数最长为6,但是将左端包含在内时,最大长度为8。

所以所有的加操作使用8位进行。

例如:

Box和Cfg相加的结果长度为8位。

2.无符号数和有符号数

  执行算术操作和赋值时,注意哪些操作数为无符号数、哪些操作数为有符号数非常重要。

无符号数存储在:

*线网

*一般寄存器

*基数格式表示形式的整数

  有符号数存储在:

*整数寄存器

*十进制形式的整数

  下面是一些赋值语句的实例:

reg[0:

5]Bar;

integerTab;

...

Bar=-4'd12;//寄存器变量Bar的十进制数为52,向量值为110100。

Tab=-4'd12;//整数Tab的十进制数为-12,位形式为110100。

-4'd12/4//结果是1073741821。

-12/4//结果是-3

  因为Bar是普通寄存器类型变量,只存储无符号数。

右端表达式的值为'b110100(12的二进制补码)。

因此在赋值后,Bar存储十进制值52。

在第二个赋值中,右端表达式相同,值为'b110100,但此时被赋值为存储有符号数的整数寄存器。

Tab存储十进制值-12(位向量为110100)。

注意在两种情况下,位向量存储内容都相同;但是在第一种情况下,向量被解释为无符号数,而在第二种情况下,向量被解释为有符号数。

  下面为具体实例:

Bar=-4'd12/4;

Tab=-4'd12/4;

Bar=-12/4

Tab=-12/4

  在第一次赋值中,Bar被赋于十进制值61(位向量为111101)。

而在第二个赋值中,Tab被赋于与十进制1073741821(位值为0011...11101)。

Bar在第三个赋值中赋于与第一个赋值相同的值。

这是因为Bar只存储无符号数。

在第四个赋值中,Bar被赋于十进制值-3。

  下面是另一些例子:

Bar=4-6;

Tab=4-6;

Bar被赋于十进制值62(-2的二进制补码),而Tab被赋于十进制值-2(位向量为111110)。

  下面为另一个实例:

Bar=-2+(-4);

Tab=-2+(-4);

Bar被赋于十进制值58(位向量为111010),而Tab被赋于十进制值-6(位向量为111010)。

4.2.2关系操作符

  关系操作符有:

*>(大于)

*<(小于)

*>=(不小于)

*<=(不大于)

  关系操作符的结果为真

(1)或假(0)。

如果操作数中有一位为X或Z,那么结果为X。

例如:

23>45

结果为假(0),而:

52<8'hxFF

结果为x。

如果操作数长度不同,长度较短的操作数在最重要的位方向(左方)添0补齐。

例如:

'b1000>='b01110

等价于:

'b01000>='b01110

结果为假(0)。

 

4.2.3相等关系操作符

  相等关系操作符有:

*==(逻辑相等)

*!

=(逻辑不等)

*===(全等)

*!

==(非全等)

  如果比较结果为假,则结果为0;否则结果为1。

在全等比较中,值x和z严格按位比较。

也就是说,不进行解释,并且结果一定可知。

而在逻辑比较中,值x和z具有通常的意义,且结果可以不为x。

也就是说,在逻辑比较中,如果两个操作数之一包含x或z,结果为未知的值(x)。

  如下例,假定:

Data='b11x0;

Addr='b11x0;

那么:

Data==Addr

不定,也就是说值为x,但:

Data===Addr

为真,也就是说值为1。

  如果操作数的长度不相等,长度较小的操作数在左侧添0补位,例如:

2'b10==4'b0010

与下面的表达式相同:

4'b0010==4'b0010

结果为真

(1)。

4.2.4逻辑操作符

  逻辑操作符有:

*&&(逻辑与)

*||(逻辑或) 

*!

(逻辑非)

  这些操作符在逻辑值0或1上操作。

逻辑操作的结构为0或1。

例如,假定:

 

Crd='b0;//0为假

Dgs='b1;//1为真

那么:

Crd&&Dgs结果为0(假)

Crd||Dgs结果为1(真)

Dgs结果为0(假)

对于向量操作,非0向量作为1处理。

例如,假定:

A_Bus='b0110;

B_Bus='b0100;

那么:

A_Bus||B_Bus结果为1

A_Bus&&B_Bus结果为1

并且:

!

A_Bus与!

B_Bus的结果相同。

结果为0。

如果任意一个操作数包含x,结果也为x。

!

x结果为x

4.2.5按位操作符

  按位操作符有:

*~(一元非)

*&(二元与)

*|(二元或)

*^(二元异或)

*~^,^~(二元异或非)

  这些操作符在输入操作数的对应位上按位操作,并产生向量结果。

下表显示对于不同操作符按步操作的结果。

  例如,假定,

A='b0110;

B='b0100;

那么:

A|B结果为0110

A&B结果为0100

如果操作数长度不相等,长度较小的操作数在最左侧添0补位。

例如,

'b0110^'b10000

与如下式的操作相同:

 

'b00110^'b10000

结果为'b10110。

4.2.6归约操作符

  归约操作符在单一操作数的所有位上操作,并产生1位结果。

归约操作符有:

*&(归约与)

如果存在位值为0,那么结果为0;若如果存在位值为x或z,结果为x;否则结果为1。

*~&(归约与非)

与归约操作符&相反。

*|(归约或)

如果存在位值为1,那么结果为1;如果存在位x或z,结果为x;否则结果为0。

*~|(归约或非)

与归约操作符|相反。

*^(归约异或)

如果存在位值为x或z,那么结果为x;否则如果操作数中有偶数个1,结果为0;否则结果为1。

*~^(归约异或非)

与归约操作符^正好相反。

如下所示。

假定,

A='b0110;

B='b0100;

那么:

|B结果为1

&B结果为0

~A结果为1

归约异或操作符用于决定向量中是否有位为x。

假定,

MyReg=4'b01x0;

那么:

^MyReg结果为x

  上述功能使用如下的if语句检测:

if(^MyReg===1'bx)

$display("ThereisanunknowninthevectorMyReg!

")

注意逻辑相等(==)操作符不能用于比较;逻辑相等操作符比较将只会产生结果x。

全等操作符期望的结果为值1。

4.2.7移位操作符

  移位操作符有:

*<<(左移)

*>>(右移)

  移位操作符左侧操作数移动右侧操作数表示的次数,它是一个逻辑移位。

空闲位添0补位。

如果右侧操作数的值为x或z,移位操作的结果为x。

假定:

reg[0:

7]Qreg;

...

Qreg=4'b0111;

那么:

Qreg>>2是8'b0000_0001

  VerilogHDL中没有指数操作符。

但是,移位操作符可用于支持部分指数操作。

例如,如果要计算ZNumBits的值,可以使用移位操作实现,例如:

32'b1<

同理,可使用移位操作为2-4解码器建模,如

wire[0:

3]DecodeOut=4'b1<

1];

Address[0:

1]可取值0,1,2和3。

与之相应,DecodeOut可以取值4'b0001、4'b0010、4'b0100和4'b1000,从而为解码器建模。

4.2.8条件操作符

  条件操作符根据条件表达式的值选择表达式,形式如下:

cond_expr?

expr1:

expr2

如果cond_expr为真(即值为1),选择expr1;如果cond_expr为假(值为0),选择expr2。

如果cond_expr为x或z,结果将是按以下逻辑expr1和expr2按位操作的值:

0与0得0,1与1得1,其余情况为x。

如下所示:

wire[0:

2]Student=Marks>18?

Grade_A:

Grade_C;

计算表达式Marks>18;如果真,Grade_A赋值为Student;如果Marks<=18,Grade_C赋值为Student。

下面为另一实例:

always

#5Ctr=(Ctr!

=25)?

(Ctr+1):

5;

过程赋值中的表达式表明如果Ctr不等于25,则加1;否则如果Ctr值为25时,将Ctr值重新置为5。

4.2.9连接和复制操作

  连接操作是将小表达式合并形成大表达式的操作。

形式如下:

{expr1,expr2,...,exprN}

  实例如下所示:

wire[7:

0]Dbus;

wire[11:

0]Abus;

assignDbus[7:

4]={Dbus[0],Dbus[1],Dbus[2],Dbus[3]};

//以反转的顺序将低端4位赋给高端4位。

assignDbus={Dbus[3:

0],Dbus[7:

4]};

//高4位与低4位交换。

由于非定长常数的长度未知,不允许连接非定长常数。

例如,下列式子非法:

{Dbus,5}//不允许连接操作非定长常数。

复制通过指定重复次数来执行操作。

形式如下:

{repetition_number{expr1,expr2,...,exprN}}

以下是一些实例:

Abus={3{4'b1011}};//位向量12'b1011_1011_1011)

Abus={{4{Dbus[7]}},Dbus};/*符号扩展*/

{3{1'b1}}结果为111

{3{Ack}}结果与{Ack,Ack,Ack}相同。

4.3表达式种类

  常量表达式是在编译时就计算出常数值的表达式。

通常,常量表达式可由下列要素构成:

  1)表示常量文字,如'b10和326。

  2)参数名,如RED的参数表明:

parameterRED=4'b1110;

  标量表达式是计算结果为1位的表达式。

如果希望产生标量结果,但是表达式产生的结果为向量,则最终结果为向量最右侧的位值。

习题

1.说明参数GATE_DELAY,参数值为5。

2.假定长度为64个字的存储器,每个字8位,编写Verilog代码,按逆序交换存储器的内容。

即将第0个字与第63个字交换,第1个字与第62个字交换,依此类推。

3.假定32位总线Address_Bus,编写一个表达式,计算从第11位到第20位的归约与非。

4.假定一条总线Control_Bus[15:

0],编写赋值语句将总线分为两条总线:

Abus[0:

9]和Bbus[6:

1]。

5.编写一个表达式,执行算术移位,将Qparity中包含的8位有符号数算术移位。

6.使用条件操作符,编写赋值语句选择NextState的值。

如果CurrentState的值为RESET,那么NextState的值为GO;如果CurrentState的值为GO,则NextState的值为BUSY;如果CurrentState的值为BUSY;则NextState的值为RESET。

7.如何从标量变量A,B,C和D中产生总线BusQ[0:

3]?

如何从两条总线BusA[0:

3]和BusY[20:

15]形成新的总线BusR[10:

1]?

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2