How does Verilog behave with negative numbers?

wonton picture wonton · Sep 13, 2012 · Viewed 57k times · Source

For instance, say I have a reg [7:0] myReg I assign it the value -8'D69

I know Verilog stores it as 2's complement so it should be stored as

10111011

The question I have now is if I were to perform an operation on it, say myReg/2

Would it evaluate to -34? Or would it take 10111011 and turn it into 187 then perform the division, returning 93?

Answer

Morgan picture Morgan · Sep 13, 2012

You need to remember that -8d69 is just a bit pattern. reg is a type which holds bit patterns. It is the type of variable that instructs / to perform signed or unsigned arithmetic.

If this is for synthesis bare in mind that you want to try and avoid dividers, you really want to try and avoid signed dividers. It will likely synthesis smaller with >>> 1

reg [7:0] a;
reg signed [7:0] b;
reg [7:0] c;
reg signed [7:0] d;

initial begin
  a =  -8'd69 ;
  b =  -8'd69 ;
  c =  -8'd69 ;
  d =  -8'd69 ;
  #10ns;
  a = a/2     ;
  b = b/2     ;
  #10ns;
  $display("a      : %8b, %d", a, a);
  $display("b      : %8b, %d", b, b);
  $display("c >>>1 : %8b, %d", c>>>1, c>>>1);
  $display("d >>>1 : %8b, %d", d>>>1, d>>>1);
end

Gives:

a      : 01011101,  93
b      : 11011110,  -34 
c >>>1 : 01011101,  93
d >>>1 : 11011101,  -35

>> x Shifts right by x places, >>> x Shifts right x places but sign extends for signed types.

NB: the /2 is also rounding up in my examples, >>> will round down/truncate.