SystemVerilog 中的相等运算符:== or === ?
1. 四值逻辑的逻辑运算#
在对比SystemVerilog
中的相等运算符之前,先来看一下三种最基本的逻辑运算符,下文中以·
表示与运算,以+
表示或运算,以'
表示非运算。我们都知道在逻辑代数中,只有0
和1
,那么在SystemVerilog
中,对于四值逻辑(0
、1
、z
、x
)的逻辑运算结果又会怎样呢?
logic v[4] = '{1'b0, 1'b1, 1'bz, 1'bx};
initial begin
foreach(v[i])
foreach(v[j])
$display("%b & %b : %b", v[i], v[j], v[i] & v[j]);
end
我们通过简单的代码就可以打印出四值逻辑运算的真值表:
与运算(A·B) | 0 | 1 | z | x |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
1 | 0 | 1 | x | x |
z | 0 | x | x | x |
x | 0 | x | x | x |
或运算(A+B) | 0 | 1 | z | x |
---|---|---|---|---|
0 | 0 | 1 | x | x |
1 | 1 | 1 | 1 | 1 |
z | x | 1 | x | x |
x | x | 1 | x | x |
非运算 | 0 | 1 | z | x |
---|---|---|---|---|
输出(A') | 1 | 0 | x | x |
由输出结果可知,四值逻辑运算的结果只有0
、1
和x
,并且与常量0
和1
运算时,仍然满足逻辑代数的基本公式:0 · A = 0
、1 · A = A
、0 + A = A
、1 + A = 1
;以及满足公式:A · A = A
、A + A = A
。
只不过输出结果不包含z
,z
参与运算时,同x
相同,如:1 · z = x
、0 + z = x
、z · x = x
、z + x = x
。
2. 相等运算符#
依然打印出所有的输出结果,如下所示:
== | 0 | 1 | z | x |
---|---|---|---|---|
0 | 1 | 0 | x | x |
1 | 0 | 1 | x | x |
z | x | x | x | x |
x | x | x | x | x |
!= | 0 | 1 | z | x |
---|---|---|---|---|
0 | 0 | 1 | x | x |
1 | 1 | 0 | x | x |
z | x | x | x | x |
x | x | x | x | x |
=== | 0 | 1 | z | x |
---|---|---|---|---|
0 | 1 | 0 | 0 | 0 |
1 | 0 | 1 | 0 | 0 |
z | 0 | 0 | 1 | 0 |
x | 0 | 0 | 0 | 1 |
!== | 0 | 1 | z | x |
---|---|---|---|---|
0 | 0 | 1 | 1 | 1 |
1 | 1 | 0 | 1 | 1 |
z | 1 | 1 | 0 | 1 |
x | 1 | 1 | 1 | 0 |
可以看到,===
和!==
的结果只有0
和1
,而==
和!=
的结果有0
、1
和x
。以上结果都是针对单比特值的比较运算,那么对于多比特数据的相等比较运算,结果如何呢?
initial begin
$display("%b == %b : %b", 4'b1010, 4'b1011, 4'b1010 == 4'b1011); // 0
$display("%b != %b : %b", 4'b1010, 4'b1011, 4'b1010 != 4'b1011); // 1
$display("%b == %b : %b", 4'b1010, 4'b10x0, 4'b1010 == 4'b10x0); // x
$display("%b == %b : %b", 4'b1010, 4'b10x1, 4'b1010 == 4'b10x1); // 0
$display("%b != %b : %b", 4'b1010, 4'b10x0, 4'b1010 != 4'b10x0); // x
$display("%b != %b : %b", 4'b1010, 4'b10x1, 4'b1010 != 4'b10x1); // 1
$display("%b == %b : %b", 4'b1x10, 4'b1x10, 4'b1x10 == 4'b1x10); // x
$display("%b == %b : %b", 4'b1z10, 4'b1x10, 4'b1z10 == 4'b1x10); // x
$display("%b != %b : %b", 4'b1x10, 4'b1x10, 4'b1x10 != 4'b1x10); // x
$display("%b != %b : %b", 4'b1z10, 4'b1x10, 4'b1z10 != 4'b1x10); // x
$display("-----------------------------------------------------");
$display("%b === %b : %b", 4'b1010, 4'b1011, 4'b1010 === 4'b1011); // 0
$display("%b !== %b : %b", 4'b1010, 4'b1011, 4'b1010 !== 4'b1011); // 1
$display("%b === %b : %b", 4'b1010, 4'b10x0, 4'b1010 === 4'b10x0); // 0
$display("%b === %b : %b", 4'b1010, 4'b10x1, 4'b1010 === 4'b10x1); // 0
$display("%b !== %b : %b", 4'b1010, 4'b10x0, 4'b1010 !== 4'b10x0); // 1
$display("%b !== %b : %b", 4'b1010, 4'b10x1, 4'b1010 !== 4'b10x1); // 1
$display("%b === %b : %b", 4'b1x10, 4'b1x10, 4'b1x10 === 4'b1x10); // 1
$display("%b === %b : %b", 4'b1z10, 4'b1x10, 4'b1z10 === 4'b1x10); // 0
$display("%b !== %b : %b", 4'b1x10, 4'b1x10, 4'b1x10 !== 4'b1x10); // 0
$display("%b !== %b : %b", 4'b1z10, 4'b1x10, 4'b1z10 !== 4'b1x10); // 1
end
对于===
和!==
的输出结果比较容易理解,只有0
和1
嘛;而对于==
和!=
的部分输出结果,是否有些困惑呢?比如对比这几个输出:
# 1010 == 10x0 : x
# 1010 == 10x1 : 0
# 1x10 == 1x10 : x
不要被这些结果所迷惑,实际上,这四个相等运算符的规则很简单,都是逐位比较操作数(bit for bit)。对于相等比较,对逐位比较的结果再进行与运算;而对于不相等比较,对逐位比较的结果再进行或运算。比如4'b1010 == 4'b10x0
,则等价于(1'b1 == 1'b1) & (1'b0 == 1'b0) & (1'b1 == 1'bx) & (1'b0 == 1'b0)
,即1'b1 & 1'b1 & 1'bx & 1'b1
,所以结果为1'bx
;而对于4'b1010 === 4'b10x0
,则等价于(1'b1 === 1'b1) & (1'b0 === 1'b0) & (1'b1 === 1'bx) & (1'b0 === 1'b0)
,即1'b1 & 1'b1 & 1'b0 & 1'b1
,所以结果为1'b0
;再比如4'b1010 != 4'b10x1
,则等价于(1'b1 != 1'b1) | (1'b0 != 1'b0) | (1'b1 != 1'bx) | (1'b0 != 1'b1)
,即1'b0 | 1'b0 | 1'bx | 1'b1
,所以结果为1'b1
。
3. 关于数据的逻辑值#
首先,上文中所涉及到的与或非运算,我所使用的都是按位与(&
)、按位或(|
)、按位非(~
),因为对于单比特数据的运算,实际上其与逻辑与(&&
)、逻辑或(||
)、逻辑非(!
)的运算结果相同,如1'b1 & 1'bx
和1'b1 && 1'bx
的结果都是1'bx
。那么对于多比特的数据,其逻辑值怎么判断呢?也就是说,比如代码中有if (4'b10x0) begin "something" end
,那something
会不会运行呢,即4'b10x0
的逻辑值是真是假呢?我这里使用两个逻辑非(!
)来得到逻辑值:!(!4'b10x0)
。
initial begin
$display("4'b%b : %b", 4'b0000, !(!4'b0000)); // 0
$display("4'b%b : %b", 4'b1010, !(!4'b1010)); // 1
$display("4'b%b : %b", 4'b1x10, !(!4'b1x10)); // 1
$display("4'b%b : %b", 4'b1z10, !(!4'b1z10)); // 1
$display("4'b%b : %b", 4'bxxxx, !(!4'bxxxx)); // x
$display("4'b%b : %b", 4'bzzzz, !(!4'bzzzz)); // x
$display("4'b%b : %b", 4'bxx00, !(!4'bxx00)); // x
$display("4'b%b : %b", 4'bz0z0, !(!4'bz0z0)); // x
end
实际上,就是对数据的所有位进行或运算,就得到了该数据的逻辑值,所以if (4'b10x0) begin "something" end
会执行something
。这一部分,主要是想说明,对于四值数据,无论是与或非逻辑运算,还是==
和!=
相等比较运算,结果都可能出现x
,且! 1'bx
结果还是1'bx
,所以下面三种写法,if
条件都不成立,最终都只会执行Do ELSE
。即,当使用==
和!=
比较四值数据时,结果可能会得到x
,并随之出现我们预期之外的效果,这是我们不希望的,所以在验证代码中比较四值数据时,要使用===
和!==
。
initial begin
if ( 4'b1010 == 4'b10x0 )
$display("Do IF");
else
$display("Do ELSE");
if ( 4'b1010 != 4'b10x0 )
$display("Do IF");
else
$display("Do ELSE");
if ( !(4'b1010 == 4'b10x0) )
$display("Do IF");
else
$display("Do ELSE");
end
作者:bitlogic
出处:https://www.cnblogs.com/bitlogic/p/14589903.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人