1. 表达式
表达式
是由 操作数
和 操作符
构成,其目的是根据操作符的意义得到一个计算结果。
2. 操作数
操作数可以是任意数据类型,操作数可以是常数(parameter),整数(integer),实数(real),线网(wire),寄存器(reg),
时间(time),位选(a[7:2])及函数(function)调用。
3. 操作符
verilog 中提供了大约 9 种操作符,分别是算术、关系、等价、逻辑、按位、归约、移位,拼接、条件操作符。
同类型操作符之间,除条件操作符从右往左关联,其余操作符都是自左向右关联。
圆括号内表达式优先执行。
例如:
/// 没有条件操作符时,自左向右关联
/// 3行等价于4行
a+b-c
(a+b)-c
/// 有条件操作符时,自右向左关联
/// 8行等价于9行
a ? b : c ? d : e ;
a ? b : (c ? d :f) ;
不同操作符之间,优先级是不同的。
- 圆括号的优先级最高。
- 没有圆括号时,verilog 会根据操作符优先级对表达式进行计算。
操作符 | 操作符号 | 优先级 |
---|---|---|
单目运算 | +、-、!、~ | 最高 |
乘、除、取余 | *、/、% | |
加、减 | +、- | |
移位 | >>、<< | |
关系 | >、<、>=、<= | |
等价 | ==、!=、===、!=== | |
归约 | &、~& | |
、~ | ||
|、~| | ||
逻辑 | && | |
|| | ||
条件 | ?: | 最低 |
4. 算术操作符
算术操作符包括 单目操作符
和 双目操作符
。
双目操作符对 2 个操作数进行算术运算,包括加减乘除,求幂(**),取余 (%)。
例如:
reg [7:0] a ;
reg [7:0] b ;
reg [15:0] c ;
a = 8'b1001_1001 ;
b = 8'b1000_0001 ;
c = a + b ; /// c = 16'b1_0001_1010
c = a - b ; /// c = 16'b1_1000
c = a * b ; /// c = 16'b100_1101_0001_1001
c = a / b ; /// c = 16'b1
5. 关系操作符
关系操作符有大于(>), 小于(<), 大于等于(>=), 小于等于(<=)。
关系操作符的正常结果有 2种,真(1)或假(0)。
如果操作数种有一位为 x 或 z,那么结果为 x。
6. 等价操作符
等价操作符包括逻辑相等(==), 逻辑不等(!=), 全等(===), 非全等(!==).
等价操作符的正常结果有 2种:真(1)或假(0)。
逻辑相等/不相等操作符不能比较 x 或 z,当其中一个操作数包含 x 或 z 时,那么结果为不确定值。
全等比较时,如果按位比较有相同的 x 或 z,返回结果也可以为 1。也就是说 全等比较的两个操作数可以包含 x 或 z
。
例如:
a = 8'b1000_xxx1 ;
b = 8'b1000_xxx1 ;
/// 逻辑相等时
a == b ; /// 结果为x
/// 全等时
a == b ; /// 结果为1
7. 逻辑操作符
逻辑操作符主要有 3个:逻辑与(&&)
,逻辑或(||)
,逻辑非(!)
。
逻辑操作符的计算结果是一个 1 bit 的值,0(假),1(真),x(不确定)。
笔记
- 如果一个操作数为 0,那么它等价于逻辑 0。
- 如果一个操作数为非 0,那么它等价于逻辑 1。
- 如果一个操作数任意一位为 x 或 z,那么它等价于 x。
8. 按位操作符
按位操作符包括:取反/非(~)
, 与(&)
,或(|)
,异或(^)
,同或(~^)
。
按位操作符需要对 2 个操作数的 每 1 bit 数据都要进行按位操作
。
取反操作符
只有一个操作数,它对这个操作数的每 1 bit 数据进行取反操作。
笔记
如果两个操作数位宽不相等,就用 0 向左扩展补充较短的操作数。
9. 归约操作符
归约操作符包括:归约与(&)
,归约与非(~&)
,归约或(|)
,归约或非(~|)
,归约异或(^)
,归约同或(~^)
。
归约操作符只有一个操作数,它对这个向量操作数逐位进行操作,最终产生一个1bit结果
。
笔记
归约操作符、按位操作符和归约操作符都使用相同的符号表示,因此有时候容易弄混。
区分这些操作符的关键是分清操作数的数目(1 个操作数还是多个操作数),和计算结果的规则。
10. 移位操作符
移位操作符包括:左移(<<)
,右移(>>)
,算术左移(<<<)
,算术右移(>>>)
。
移位操作符是双目操作符,两个操作数分别表示进行移位的向量信号(操作符左侧)与移动的位数(操作符右侧)。
算术左移和逻辑左移时,右边低位会补 0。
逻辑右移时,左边高位会补 0。
算术右移时,左边高位补充符号位。
例如:
/// 负数
8'b1000_0001>>2 = 8'b1110_0000
/// 正数
8'b1000_0001>>2 = 8'b0010_0000
11. 条件操作符
条件操作符有 3个操作符。
格式
【condition_expression】?【true_expression】:【false_expression】
如果 condition_expression
成立,那么结果为 true_expression
。
如果 condition_expression
不成立,那么结果为 false_expression
。
例如:
/// 如果b==1成立,那么a=c
/// 如果b==1不成立,那么a=d
assign a = (b == 1) ? c : d ;