Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

32-bit signed, unsigned and integers and overflows

155 views
Skip to first unread message

Andy Peters

unread,
Mar 8, 2000, 3:00:00 AM3/8/00
to
Today's gotcha:

given:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

and some constants:

constant ADDR : std_logic_vector (31 downto 0) :=
std_logic_vector(to_unsigned(16#00008000#,32)); -- base address
-- setting a mask bit to 1 disables that bit.
constant MASK : std_logic_vector (31 downto 0) :=
std_logic_vector(to_unsigned(16#FFFF00FF#,32)); -- address mask

I get the following complaints (line 45 is where MASK is defined):

ERROR: h:/gccoadd/fpga/cfg964/cfg964.vhd(45): Value -65281 is out of range 0
to 2147483647.
ERROR: h:/gccoadd/fpga/cfg964/cfg964.vhd(45): Value -65281 is out of range 0
to 2147483647.

to_unsigned seems to be failing.

(FPGA Express also complains: "Integer overflow while scanning numeric
literal.")

Now, if I change to_unsigned to to_signed, ModelSim is happy, but FPGA
Express still complains.

I know that integers default to 32 bits. what's going on here?

-- a
-----------------------------------------
Andy Peters
Sr Electrical Engineer
National Optical Astronomy Observatories
950 N Cherry Ave
Tucson, AZ 85719
apeters (at) noao \dot\ edu

"Money is property; it is not speech."
-- Justice John Paul Stevens

Tom Moog

unread,
Mar 8, 2000, 3:00:00 AM3/8/00
to

In one case the formal is integer, whereas in the
other case the formal is natural. Also, ModelSim
vcom doesn't really care about integer overflow
(last time I checked). Thus 65536*65536 gives the
result 0 and 16#FFFF_FFFF is (-1) rather than the
correct value of 2**32-1 (which is too big for
systems which use 32 bit two's complement representation).
Also, please note that VHDL does not have the concept
of a negative integer literal (e.g. -1 is really
unary-minus-operator(1)).

Tom Moog
Polhode, Inc.

Andy Rushton

unread,
Mar 9, 2000, 3:00:00 AM3/9/00
to
The problem is that the value 16#ffff0000# is an integer literal, so the
compiler converts it to an integer value. This could be seen as a
negative value (because integer is a 32-bit two's complement
representation and your sign bit is '1') or as a large positive value
beyond the range of integer. In the first interpretation, when you pass
this value to the to_unsigned function which takes a natural argument,
it is of course out of range (sounds like what ModelSim is doing). In
the second interpretation the value itself overflows integer (sounds
like what FPGAExpress is doing).

Generally, integers are too deficient to use much. You often end up
having to write bit-strings instead.

Andy

-- Andy Rushton
-- ECS Department, Southampton University, UK
-- mailto:A.J.R...@ecs.soton.ac.uk
-- http://www.ecs.soton.ac.uk/~ajr1

Brian Drummond

unread,
Mar 9, 2000, 3:00:00 AM3/9/00
to
On Wed, 8 Mar 2000 11:15:49 -0700, "Andy Peters"
<apeters...@nospam.noao.edu.nospam> wrote:

>Today's gotcha:
>
>given:
[...]


> constant MASK : std_logic_vector (31 downto 0) :=
> std_logic_vector(to_unsigned(16#FFFF00FF#,32)); -- address mask
>
>I get the following complaints (line 45 is where MASK is defined):
>
>ERROR: h:/gccoadd/fpga/cfg964/cfg964.vhd(45): Value -65281 is out of range 0
>to 2147483647.
>ERROR: h:/gccoadd/fpga/cfg964/cfg964.vhd(45): Value -65281 is out of range 0
>to 2147483647.
>
>to_unsigned seems to be failing.

Yup, this got me a couple of years ago.

Some tools don't seem to mind ... but ModelSim is more strictly
compliant. The problem (IIRC) is that unsigned integers are defined as
being the _positive_ range of the integer value, rather than (as in C)
the _entire_ bitfield represented as a positive integer...
thus you have 32-bit signed integers but only 31 bit unsigneds.

Grrrr...

Paul? Care to shed any light on the reason for this?

I resorted to bit_vector literals instead X"FFFF00FF" etc...
(find/replace 16# with X" etc...)

(I would have used std_logic_vector literals, and save the conversion
functions, but one tool was happy to take X"FFFF00FF" while the other
(Autologic?) insisted on "11111111111111110000000011111111" ...ugh!
I suspect this latter point is a VHDL'87/93 matter and now I use the
X"FFF" format to define slv's directly...

Another advantage is that you aren't restricted to <=31 bit values
either, I have 40-bit constants and all sorts where appropriate.

- Brian


Andy Peters

unread,
Mar 9, 2000, 3:00:00 AM3/9/00
to
thanks to all who replied.

the best solution was to use a bit vector. too much vhdl'87 and when I
started doing things '93-wise, I forgot about being able to do X"600DF00D"
and such.

Andreas Gieriet

unread,
Mar 9, 2000, 3:00:00 AM3/9/00
to Andy Peters
Andy,

Try the code below, it should work.

Andy Peters wrote:
>
> Today's gotcha:
>
> given:
>

> library ieee;
> use ieee.std_logic_1164.all;
> use ieee.numeric_std.all;
>
> and some constants:
>

> constant ADDR : std_logic_vector (31 downto 0) :=
> std_logic_vector(to_unsigned(16#00008000#,32)); -- base address

to_stdlogicvector(bit_vector'(X"00008000"));

> -- setting a mask bit to 1 disables that bit.

> constant MASK : std_logic_vector (31 downto 0) :=
> std_logic_vector(to_unsigned(16#FFFF00FF#,32)); -- address mask

to_stdlogicvector(bit_vector'(X"FFFF00FF"));

(VHDL'93 would even be simpler: X"FFFF00FF")

>
> I get the following complaints (line 45 is where MASK is defined):
>
> ERROR: h:/gccoadd/fpga/cfg964/cfg964.vhd(45): Value -65281 is out of range 0
> to 2147483647.
> ERROR: h:/gccoadd/fpga/cfg964/cfg964.vhd(45): Value -65281 is out of range 0
> to 2147483647.
>
> to_unsigned seems to be failing.
>

> (FPGA Express also complains: "Integer overflow while scanning numeric
> literal.")
>
> Now, if I change to_unsigned to to_signed, ModelSim is happy, but FPGA
> Express still complains.
>
> I know that integers default to 32 bits. what's going on here?
>

The Integer type is required to support
at least the range -(2**31-1) to (2**31-1) (see LRM'93, pp36).

Instead of performing two translations (literal -> signed -> slv) do
only one transformation (bitvec -> slv). This performs only a
bit-pattern "copy" from the bit vector to the std_logic_vector.

--

_/_/_/_/ _/_/_/ Andreas Gieriet, VP R&D
_/ _/ _/ DS Diagonal Systems
_/ _/ _/_/ phone:+41-1-905-6060
_/ _/ _/ mailto:an...@diagonal.ch
_/_/_/_/ _/_/_/ http://www.diagonal.com/

me...@mench.com

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
On Thu, 09 Mar 2000 14:40:22 +0000, Brian Drummond
<br...@shapes.demon.co.uk> wrote in article
<9ibfcso065to8dsnf...@4ax.com>:

> On Wed, 8 Mar 2000 11:15:49 -0700, "Andy Peters"

> <apeters...@nospam.noao.edu.nospam> wrote:

>>Today's gotcha:
>>
>>given:
> [...]


>> constant MASK : std_logic_vector (31 downto 0) :=
>> std_logic_vector(to_unsigned(16#FFFF00FF#,32)); -- address mask
>>

>>I get the following complaints (line 45 is where MASK is defined):
>>
>>ERROR: h:/gccoadd/fpga/cfg964/cfg964.vhd(45): Value -65281 is out of range 0
>>to 2147483647.
>>ERROR: h:/gccoadd/fpga/cfg964/cfg964.vhd(45): Value -65281 is out of range 0
>>to 2147483647.
>>
>>to_unsigned seems to be failing.

> Yup, this got me a couple of years ago.

> Some tools don't seem to mind ... but ModelSim is more strictly
> compliant. The problem (IIRC) is that unsigned integers are defined
> as being the _positive_ range of the integer value, rather than (as
> in C) the _entire_ bitfield represented as a positive integer...
> thus you have 32-bit signed integers but only 31 bit unsigneds.

> Grrrr...

> Paul? Care to shed any light on the reason for this?

Well, in C-like languages, unsigned and int are separate (although
related) types. In VHDL, Natural and Positive are subtypes of Integer
and therefore their ranges must be subsets of Integer. If Integer is
supposed to fit in 32 bits and encompass both positive and negative
values, then Natural and Postive are necessarily unable to "use the
extra bit" in the way that C does.

Hope this helps,

Paul
--
Paul Menchini | "Outside of a dog, a book is probably man's
Cadence PCB Design Systems | best friend, and inside of a dog, it's too
me...@mench.com | dark to read."
www.orcad.com | --Groucho Marx

Brian Drummond

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to
On 22 Mar 2000 15:02:42 -0500, me...@mench.com wrote:

>On Thu, 09 Mar 2000 14:40:22 +0000, Brian Drummond
><br...@shapes.demon.co.uk> wrote in article
><9ibfcso065to8dsnf...@4ax.com>:
>
>> On Wed, 8 Mar 2000 11:15:49 -0700, "Andy Peters"
>> <apeters...@nospam.noao.edu.nospam> wrote:
>
>>>Today's gotcha:

>>>to_unsigned seems to be failing.


>
>> Yup, this got me a couple of years ago.
>

>> The problem (IIRC) is that unsigned integers are defined
>> as being the _positive_ range of the integer value, rather than (as
>> in C) the _entire_ bitfield represented as a positive integer...
>> thus you have 32-bit signed integers but only 31 bit unsigneds.
>
>> Grrrr...
>
>> Paul? Care to shed any light on the reason for this?
>
>Well, in C-like languages, unsigned and int are separate (although
>related) types. In VHDL, Natural and Positive are subtypes of Integer
>and therefore their ranges must be subsets of Integer. If Integer is
>supposed to fit in 32 bits and encompass both positive and negative
>values, then Natural and Postive are necessarily unable to "use the
>extra bit" in the way that C does.
>
>Hope this helps,

I think I was actually asking if there was a reason _why_ that decision
was made, rather than having Integer and Natural being closely related
types as in C.

Or was it "just one of those things"?

Regards,
- Brian

me...@mench.com

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to
On Thu, 23 Mar 2000 16:12:12 +0000, Brian Drummond
<br...@shapes.demon.co.uk> wrote in article
<63fkdskhcrh7tdp0i...@4ax.com>:

> On 22 Mar 2000 15:02:42 -0500, me...@mench.com wrote:

>>Well, in C-like languages, unsigned and int are separate (although
>>related) types. In VHDL, Natural and Positive are subtypes of Integer
>>and therefore their ranges must be subsets of Integer. If Integer is
>>supposed to fit in 32 bits and encompass both positive and negative
>>values, then Natural and Postive are necessarily unable to "use the
>>extra bit" in the way that C does.

> I think I was actually asking if there was a reason _why_ that


> decision was made, rather than having Integer and Natural being
> closely related types as in C.

> Or was it "just one of those things"?

Well, natural is really a range-restricted integer. VHDL's type model
was developed from Ada, and this is the way Ada does it. Since VHDL
does not have implicit type conversions (with two, minor exceptions)
doing it the "C way" would involve many more explicit conversions.

Of course, you could always use the unsigned package, and make the
integers any size you like....

0 new messages