15

So it ended up that the bug that had kept me on for days, was a section of code that should have evaluated to False evaluating to True. My initial code went something like:

if(~x && ~y) begin
    //do stuff
end

i.e. If x is NOT ONE and y is NOT ONE then do stuff. Stepping through the debugger, I realized even though x was 1 the expression in the if-statement still resulted into TRUE and the subsequent code was executed.

However, when I changed the statement to:

if(x == 0 && y == 0) begin
//do stuff
end

and also tried:

if(!x && !y) begin
//do stuff
end 

the code within the if-statement was not evaluated which was the expected behaviour. I understand that ~ is a bitwise negation and ! a logical negation, but shouldn't (~x && ~y) and (!x && !y) evaluate to the same thing? I'm afraid the codebase is too large, so I can't paste it here, but this was the only alteration I made to make the code to work as I intended. Thanks.


In response, to one of the comments below, I have created a test-case to test this behaviour:

`timescale 10ns/1ns

module 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

And strangely enough, "First case executed" is printed to confirm the original behaviour I observed.

toolic
  • 46,418
  • 10
  • 64
  • 104
SleepingSpider
  • 1,056
  • 4
  • 17
  • 35
  • guessing, but wouldn't bitwise negation would be something like `~0xAA = 0x55`, v.s. `!0xAA` being the equivalent of "0xAA is not zero, so evaluate to true". – Marc B May 07 '13 at 17:09
  • @Marc B Yeah, that's an important difference. However in this case, both x and y are 1 bit long. If x is "1", I'd expect a bitwise negation ~x to be "0".. – SleepingSpider May 07 '13 at 17:14
  • One bit long? How odd. Can you make a test project to display the values of `x`, `!x`, `~x`, `y`, `!y`, `~y`, and `(~x && ~y)` and `(!x && !y)`? – This isn't my real name May 07 '13 at 17:31

2 Answers2

8

I see. The variable "x" in the above code was a Verilog integer (integer x;). However, an integer variable is represented by Verilog as a 32-bit integer number. So even though x was "1" as I had observed, ~x will not result in "0" but in "11111111111111111111111111111110"! And so it's no surprise that the First Case was executed. My fault. Thanks for all the answers.

SleepingSpider
  • 1,056
  • 4
  • 17
  • 35
  • Glad you worked it out. The lesson is to use the `reg` & `wire` types in classic Verilog, or the `bit` & `logic` types in modern Verilog, and size your signals appropriately. (Be warned, those types aren't equivalent) – Paul S May 09 '13 at 08:20
  • According to IEEE Std 1364, an `integer` may be implemented as larger than 32 bits. IEEE Std 1800 (SystemVerilog) fixes the width to 32 bits. – toolic May 31 '20 at 17:14
3

~ is a bit-wise operator and returns the invert of the argument.

! is a logical operator and returns a single bit.

Example:

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

For your example:

if(~x && ~y) begin
    //do stuff
end

Is effectively the same as:

if(x!='1 && y!='1) begin // '1 means the with of x all 1s and the with of y all 1s
    //do stuff
end

Generally the best coding style is to use logical operators inside if statements. Only use bit-wise operators with data assignment manipulations.

Greg
  • 16,013
  • 5
  • 43
  • 61
  • FYI - The `'1` syntax is not valid Verilog syntax. This construct was introduced in SystemVerilog. – dwikle May 07 '13 at 20:18
  • Not knowing the widths of `x` and `y`, I decided using SystemVeilog syntax and placed a note explain what `'1` is intended for. Since the release of IEEE Std 1800-2009, Verilog and SystemVerilog are one and the same . (Mentioned in the abstract, maybe someone else can find a better citation.) – Greg May 07 '13 at 21:28
  • That use of ~ in the if statement is not very clear. I would always use ~ with a comparison. Also my simulator does not think Verilog and SystemVerilog are the same thing. Verilog is often used to refer to the 1995 or 2001 specs before SystemVerilog it makes a big difference to those using older tools. – Morgan May 08 '13 at 06:54