微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Verilog表达式

Verilog表达式

时间:06-06 来源:互联网 点击:

表达式由操作数和操作符组成。表达式可以在出现数值的任何地方使用。

操作数

   操作数可以是以下类型中的一种:
   1) 常数
   2) 参数
   3) 线网
   4) 寄存器
   5) 位选择
   6) 部分选择 
   7) 存储器单元
   8) 函数调用

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)在下例中处理不同。

integer Cone;
. . .
Cone = -44/4
Cone = -6'o54/ 4;

   注意-44和-6'o54以相同的位模式求值;但是-44作为有符号数处理,而-6'o54作为无符号数处理。因此第一个字符中Cone的值为-11,而在第二个赋值中Cone的值为1073741813。

1.2 参数

  参数类似于常量,并且使用参数声明进行说明。下面是参数说明实例。

parameter LOAD = 4'd12, STORE = 4'd10;
LOAD 和STORE为参数的例子,值分别被声明为12和10。

1.3 线网

   可在表达式中使用标量线网(1位)和向量线网(多位)。下面是线网说明实例。

wire [0:3] Prt; //Prt 为4位向量线网。
wire Bdq; //Bbq 是标量线网。

   线网中的值被解释为无符号数。在连续赋值语句中,

assign Prt = -3;
Prt被赋于位向量1101,实际上为十进制的13。在下面的连续赋值中,
assign Prt = 4'HA;
Prt被赋于位向量1010,即为十进制的10。

1.4 寄存器

   标量和向量寄存器可在表达式中使用。寄存器变量使用寄存器声明进行说明。例如:

integer TemA, TemB;
reg [1:5] State;
time Que [1:5];

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

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

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

1.5 位选择

   位选择从向量中抽取特定的位。形式如下:

net_or_reg_vector [bit_select_expr]

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

State [1] State [4] //寄存器位选择。
Prt [0] | Bbq //线网位选择。

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

1.6 部分选择

   在部分选择中,向量的连续序列被选择。形式如下:

net_or_reg_vector [msb_const_expr:1sb_const_expr]

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

State [1:4] //寄存器部分选择。
Prt [1:3] //线网部分选择。
选择范围越界或为x、z时,部分选择的值为x。

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]是合法的表达式。

1.8 函数调用

   表达式中可使用函数调用。函数调用可以是系统函数调用(以$字符开始)或用户定义的函数调用。例如:

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

操作符

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

   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

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]中。
   在较大的表达式中,中间结果的长度如何确定?在Verilog HDL中定义了如下规则:表达式中的所有中间结果应取最大操作数的长度(赋值时,此规则也包括左端目标)。考虑另一个实例:

wire [4:1] Box, Drt;
wire [1:5] Cfg;
wire [1:6] Peg;
wire [1:8] Adt;
. . .
assign Adt = (Box + Cfg) + (Drt + Peg);

   表达式左端的操作数最长为6,但是将左端包含在内时,最大长度为8。所以所有的加操作使用8位进行。例如:Box和Cfg相加的结果长度为8位。

2. 无符号数和有符号数
   执行算术操作和赋值时,注意哪些操作数为无符号数、哪些操作数为有符号数非常重要。无符号数存储在:
* 线网
* 一般寄存器
* 基数格式表示形式的整数
   有符号数存储在:
* 整数寄存器
* 十进制形式的整数
   下面是一些赋值语句的实例:

reg [0:5] Bar;
integer Tab;
. . .
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)。注意在两种情况下,位向量存储内容都相同;但是在第一种情况下,向量被解释为无符号数,而在第二种情况下,向量被解释为有符号数。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top