Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

verilog "~" operator in addition operation gives unwanted result

In the following simplified Verilog code:

wire [31:0] depth;
wire mode_u2 = 1'h0;

assign depth = 'h80 + (~mode_u2);

if I do a display on depth, and simulate it with VCS (2014.12-1)

$display("depth is 0x%2x", depth);

i'm getting 0x7f, instead of expected 0x81. it seems like ~mode_u2 is treated as minus 1.

If I change ~mode_u2 to !mode_u2. I get 0x81 as expected.

what's more interesting is if i do wire mode = ~mode_u2 and then assign depth = 'h80 + (~mode) instead of 0x80, i get 0x7e

Am I missing something here?

Can someone explain why ~ behaves this way in a + operation? Or is this one of those simulation and synthesis being different situation?

Many thanks!!

Willie

like image 683
shakimura Avatar asked Oct 31 '22 09:10

shakimura


1 Answers

The operands of the add operator need to be extended to the size of left hand side (or the max width of the two operands depending on the context) before the addition is done.

In this case mode_u2 needs to be extended to 32 bits. I wasn't able to find a reference for this, but looks like the bit extension has precedence over the ~ operator. That means:

depth = 'h80 + (~mode_u2) = 
         32'h0000_0080 + (~32h0000_0000) = 
         32'h0000_0080 + 32'hffff_ffff = 
         32'h0000_007f

The result of ! operator, however by definition is a single bit, and my guess is that the bit extension happens twice:

depth = 'h80 + (!mode_u2) = 
         32'h0000_0080 + (!32'h0000_0000) = 
         32'h0000_0080 + 1'h1 = 
         32'h0000_0080 + 32'h0000_0001 = 
         32'h0000_0081

Similarly for mode:

depth = 'h80 + (~mode) = 
         32'h0000_0080 + (~32'h0000_0001) = 
         32'h0000_0080 + 32'hffff_fffe = 
         32'h0000_007e
like image 177
Ari Avatar answered Nov 15 '22 09:11

Ari