1
\$\begingroup\$

There are so many resources online talking about how to represent and extend signed numbers in Verilog, but I still can not get it. Let's say I have a number 244, which is 'b1111_0100, or 'hF4. If I want to represent this number in signed decimal, should I need to declare the size with one extra bit for the sign?

8'sd244 or 9'sd244               // signed 244?
8'sb1111_0100 or 9'sb1111_0100   // which one is correct 244?
8'shF4    or 9'shf4              // Do I need 0FA, or it is assumed?

Even more confusion comes with negative numbers: do I need to represent them in 2's complement format? How about the size? It would be nice if someone could give an explanation with example in the <size>'<signed><format><value> format.

\$\endgroup\$
1
\$\begingroup\$

To declare a negative number in 2's complement form, you place the negative sign in front of the width specifier, for example

-8'H10

Would be the value of -16, and would have the same bit pattern as the unsigned value 8'HF0

You do indeed need to include the sign bit in your width considerations, and it is of course essentially up to you to keep track of which vectors are to to be interpreted as signed and which as unsigned.

\$\endgroup\$
  • \$\begingroup\$ How is "-" usage different from "s"? If I want to correctly represent two numbers +250 and -250, would it be 9'sb0_1111_1010 and 9'sb1_0000_0110 respectively? The same way, should I represent 8'd250 and -9'sd250? \$\endgroup\$ – Nazar Sep 11 '17 at 2:01
1
\$\begingroup\$

You need to separate the bit-pattern value expressed by a numeric literal from signed or unsigned type. Signedness only comes into play when a value gets used in another expression, and it also determines the interpreted minimum/maximum values. The <size>, <radix>, and <value> parts of a literal give you an unsigned bit pattern. If you are working with an 8-bit expression, the largest signed value you can represent is 127.

So if you have 8'sd244, that will be interpreted as a signed negative number(-11, I think). If you are trying to represent -244, you need at least a 9-bit wide value. Verilog has tricky rules when mixing signed and unsigned data types. But in general, the MSB of a signed expression gets sign-extended when used in a larger width signed expression.

\$\endgroup\$
0
\$\begingroup\$

For representing signed numbers, you definitely need 1 extra bit, like if +250 in unsigned could be represented in 8 bits but both +250 and -250 when declared unsigned would need 9 bits.

You can try out this small program and see yourself

`timescale 1ns/1ps

module tb;
  reg signed [8:0] a;
  reg [7:0] b;

  initial
    begin
      a = 9'b011111010;
      b = 8'b11111010;
      $display("a is %d and b is %d", a, b);
      a = 9'b100000110;
      b = ~b + 1;
      $display("a is %d and b is %d", a, b);
    end
endmodule

So, +250 when represented in 8 bits (unsigned), if done 2's complement does not produce -250. To get -250, you need 9 bits and that when 2's complemented produces -250 correctly.

So 9'sb011111010 = +250
   9'sb100000110 = -250
   8'ub11111010   = +250
\$\endgroup\$
  • \$\begingroup\$ Wouldn't your very last example be interpreted as -6 (8'sb11111010) ? \$\endgroup\$ – Nazar Sep 11 '17 at 12:13
  • \$\begingroup\$ No 8'b11111010 is not signed and would correctly represent 250. You can run the code and check \$\endgroup\$ – Shankhadeep Mukerji Sep 11 '17 at 18:26

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.