Reputation: 1496
I had some strange behavior when synthesizing some code with the expression:
logic [7:0] x;
//...
if ((~x) == 0)
In a situation where x
is 8'hff
), the above boolean evaluates to false. I saw this behavior in synthesized hardware and double-checked it in simulation.
Of course, changing the expression to
if ((~x) == '0)
Gives me the behavior I expect; It evaluates to true when x
is 8'hff
.
My question:
Why does adding the tick mark fix this problem? 0
by itself should give me an unsigned integer with width 32, and (~x)
should give me an 8-bit unsigned number. Whether or not I specify the width of my 0
, the result ought to be the same.
I assume that I'm missing something about signedness or type promotion in the Verilog spec.
Example code: You can see this behavior across all Commercial simulators at this EDA playground link.
In case you have trouble accessing it, the code at the link is
module tb;
logic [7:0] x;
logic [7:0] y;
initial begin
x <= 8'hff;
y <= 8'h00;
#1;
$display("((~x) == 0) evaluates to %b", (~x) == 0); #1;
$display("((~x) == '0) evaluates to %b", (~x) == '0); #1;
$display("((y) == 0) evaluates to %b", (y) == 0); #1;
$display("((y) == 0) evaluates to %b", (y) == '0); #1;
$display("((~y) == ~0) evaluates to %b", (~y) == ~0); #1;
$finish;
end
endmodule
Upvotes: 0
Views: 220
Reputation: 42698
This is because operands get extended before apply any operations within the same context.
Since the width of the unsized decimal literal 0
is 32, the equality operator extends the width of the smaller operand to the width of the larger operand. So 8'hFF
becomes 32'h0000_00FF
. Then the bitwise-negation operator ~
gets applied.
The width of fill literal '0
depends on its context. When self-determined, its width is 1 bit. However, when in the context of the equality operator, its width gets extended to the width of x
, which is 8-bits.
You can get the behavior you want by using the fill literal, or making sure there is no operand extension either by:
if ((~x) == 8'b0) // No extension -- both sides are 8-bits
or use a concatenation:
if ({~x} == 8'b0)
The concatenation works because each operand of a concatenation is self-determined. Only the result of the concatenation is the context of the equality expression.
Upvotes: 1