Sle*_*der 14 boolean-logic verilog modelsim
所以它最终导致让我保持数天的错误,是一段应该评估为False评估为True的代码.我的初始代码类似于:
Run Code Online (Sandbox Code Playgroud)if(~x && ~y) begin //do stuff end
即如果x不是一个而y不是一个那么就做.通过调试器,我意识到即使x为1,if语句中的表达式仍然导致TRUE并且后续代码被执行.
但是,当我将声明更改为:
if(x == 0 && y == 0) begin
//do stuff
end
Run Code Online (Sandbox Code Playgroud)
并尝试过:
if(!x && !y) begin
//do stuff
end
Run Code Online (Sandbox Code Playgroud)
未评估if语句中的代码,这是预期的行为.我明白〜是一个有点否定的!一个逻辑否定,但不应该(~x &&~y)和(!x &&!y)评估相同的东西?我担心代码库太大了,所以我不能把它粘贴到这里,但这是我为使代码按照我的意图工作而做的唯一改动.谢谢.
作为回应,我在下面的一条评论中创建了一个测试用例来测试这种行为:
`timecale 10ns/1ns
module test_negation();
Run Code Online (Sandbox Code Playgroud)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
奇怪的是,打印出"第一个案例",以确认我观察到的原始行为.
Thi*_*ame 16
所述!
符号表示的布尔或逻辑非.对于x
除零以外的任何值,!x
计算结果为零或false,当x
为零时,!x
计算结果为1或true.
该~
符号代表位求反.值中的每个位都被切换,因此对于16位x == 0xA5A5
,~x
将评估为0x5A5A
.
的if()
条件期望评估为真或假,其中任何非零值(正或负)是真实的表达,和零是假的.
这&&
是一个逻辑AND.它需要两个表达式,当且仅当两个表达式都为真时,求值为1或者为真.同样,这里的"真实"意味着非零,正面或负面.
鉴于这一切,我们可以看到,唯一的时间~x
和!x
评估相同的值是何时x == -1
,或者,如果x
是无符号的,何时x == MAX_UNSIGNED
.
Gre*_*reg 11
~
是按位运算符并返回参数的反转。
!
是一个逻辑运算符并返回一位。
例子:
reg [7:0] bit_wise, logic_op;
initial begin
bit_wise = ~8'hA1; // bit_wise == 8'h5E
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
Run Code Online (Sandbox Code Playgroud)
对于你的例子:
if(~x && ~y) begin
//do stuff
end
Run Code Online (Sandbox Code Playgroud)
实际上等同于:
if(x!='1 && y!='1) begin // '1 means the with of x all 1s and the with of y all 1s
//do stuff
end
Run Code Online (Sandbox Code Playgroud)
一般来说,最好的编码风格是在 if 语句中使用逻辑运算符。仅将按位运算符与数据赋值操作一起使用。
我懂了。上面代码中的变量“ x”是Verilog整数(integer x;
)。但是,Verilog 将整数变量表示为32位整数。因此,即使x如我所观察到的那样为“ 1”,〜x也不会导致“ 0”而是“ 11111111111111111111111111111111110”!因此,第一案被执行并不奇怪。我的错。感谢所有的答案。