SystemVerilog 中的相等运算符:== or === ?

您所在的位置:网站首页 verilog的与或非 SystemVerilog 中的相等运算符:== or === ?

SystemVerilog 中的相等运算符:== or === ?

#SystemVerilog 中的相等运算符:== or === ?| 来源: 网络整理| 查看: 265

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. 相等运算符

image-20210328172705936

依然打印出所有的输出结果,如下所示:

== 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


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3