5

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

shakimura
  • 53
  • 2

1 Answers1

2

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
Ari
  • 7,251
  • 11
  • 40
  • 70
  • @Ari: I was thinking about the same thing, this should be the only possible explanation. However one thing worth mentioning is that, if it's doing 0x80 + all fs, then when i print 33 bits of the result depth, the MSB is NOT 1? and also, when you do + (~mode), why is it adding ~32'h0000_0001, not ~32'hffff_ffff since mode is ~mode_u2. – shakimura Feb 23 '15 at 18:38
  • 1
    @shakimura: The result of `0x80 + 32'ffff_ffff` is really 33 bits, but you only store and print 32 bits: `32'h0000_0080 + 32'hffff_ffff = 33'h1_0000_0074`, hence you don't see the MSB to be 1. Also, initially when you define it as a wire, `mode` is initialized to `1'b1` as in `wire mode = ~mode_u2 = ~1'b0= 1'b1`. Later, when you use `mode` in the addition operation, `1'b1` gets extended to 32 bits first: `32'h0000_0001`. Then, the `~` operator inverts it into `32'hffff_fffe`. – Ari Feb 23 '15 at 18:58
  • @Ari: Thanks! So expansion happens only in the addition operation, before the bitwise negation. I'll try to find any documentation on this, but i'm accepting this as the answer. Thanks again – shakimura Feb 23 '15 at 19:07
  • @shakimura: yes, expansion happens only in the addition operation. If you use `mode` or `mode_u2` elsewhere, they would expand in a different way depending on the context. There is some explanation in IEEE SystemVerilog LRM 1800-2012, Section 10.7 under "Assignment Extension and Truncation". Please update here if you found any more detailed reference related to your question. – Ari Feb 23 '15 at 19:17