What Is the Difference Between Verilog! and ~?

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.

3

2 Answers

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.

2

~ 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'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

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.

3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Marcus Vance

Marcus Vance

Cybersecurity & Digital Privacy Researcher

Marcus Vance is a cybersecurity auditor and technology writer dedicated to educating the public about online safety, data privacy regulations, enterprise security, and emerging cyber threats.

Share this article
Twitter Facebook Pinterest