所以它最终导致我连续几天的错误,是一段应该评估为False评估为True的代码。我的初始代码类似于:
if(~x && ~y) begin //do stuff end
即。如果x不是一个而y不是一个那么就做。通过调试器,我意识到即使x为1,if语句中的表达式仍然导致TRUE并且后续代码被执行。
然而,当我将声明改为:
时if(x == 0 && y == 0) begin
//do stuff
end
并尝试过:
if(!x && !y) begin
//do stuff
end
未评估if语句中的代码,这是预期的行为。我明白〜是一个有点否定的!逻辑否定,但不应该(~x& ~y y)和(!x&&!y)评估相同的东西?我担心代码库太大了,所以我不能把它粘贴到这里,但这是我为使代码按照我的意图工作而做的唯一改动。感谢。
作为回应,我在下面的一条评论中创建了一个测试用例来测试这种行为:
`时间刻度10ns / 1ns
模块test_negation();
integer x, y; initial begin x = 1; y = 0; if(~x && ~y) begin $display("%s", "First case executed"); end if(!x && !y) begin $display("%s", "Second case executed"); end if(x == 0 && y == 0) begin $display("%s", "Third case executed"); end end endmodule
奇怪的是,“首先执行的案件”被打印出来以确认我观察到的原始行为。
答案 0 :(得分:15)
!
符号表示布尔或逻辑否定。对于x
以外的任何值,!x
的计算结果为零或假,当x
为零时,!x
的计算结果为1,或者为真。
~
符号表示按位否定。值中的每个位都被切换,因此对于16位x == 0xA5A5
,~x
将评估为0x5A5A
。
if()
条件期望一个计算结果为true或false的表达式,其中任何非零(正或负)为真,零为假。
&&
是一个逻辑AND。它需要两个表达式,当且仅当两个表达式都为真时,求值为1或者为真。同样,“真实”在这里意味着非零,正面或负面。
鉴于这一切,我们可以看到~x
和!x
唯一评估相同值的时间是x == -1
,或者x
是无符号的时候x == MAX_UNSIGNED
。
答案 1 :(得分:5)
我明白了。上面代码中的变量“x”是Verilog整数(integer x;
)。但是,整数变量由Verilog表示为32位整数。所以即使x是我观察到的“1”,~x也不会导致“0”而是“11111111111111111111111111111110”!因此,First Case的执行也就不足为奇了。我的错。谢谢你的所有答案。
答案 2 :(得分:2)
~
是一个按位运算符并返回参数的反转。
!
是一个逻辑运算符,返回一位。
示例:
reg [7:0] bit_wise, logic_op;
initial begin
bit_wise = ~8'hA1; // bit_wise == 8'h6E
logic_op = !8'hA1; // logic_op == 8'b00
$display("bit_wise:%h logic_op:%h", bit_wise, logic_op); // bit_wise:5e logic_op:00
end
对于你的例子:
if(~x && ~y) begin
//do stuff
end
实际上与:
相同if(x!='1 && y!='1) begin // '1 means the with of x all 1s and the with of y all 1s
//do stuff
end
通常,最好的编码风格是在if语句中使用逻辑运算符。仅使用逐位运算符进行数据赋值操作。