Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > converting std_logic_vector to an integer without sign extension

Reply
Thread Tools

converting std_logic_vector to an integer without sign extension

 
 
Mark
Guest
Posts: n/a
 
      11-25-2009
I'm trying to elegantly convert a std_logic_vector(upper downto lower)
to an integer without sign extension using ieee.numeric_std with upper
and lower taking on values from 31 to 0 and with upper >= lower. I
cannot seem to find a syntax that doesn't generate truncation
warnings, or relies on doing some comparison.

If I use:

i:= to_integer( signed( slv(upper downto lower)));

I'll get sign extension if upper==lower (which I don't want).

To avoid sign extension, I've tried:

i:= to_integer( signed( '0' & slv(upper downto lower)));

That works great until upper=31, and lower=0---leading to a to_signed
truncation warning (since in this case we're creating a 33-bit vector
and reducing it to a 32-bit integer).

I could just check if upper==lower, and break the conversion into two
cases, but I'm wondering if there's a cleaner, more elegant way of
handling this conversion without warnings.



 
Reply With Quote
 
 
 
 
Kenn Heinrich
Guest
Posts: n/a
 
      11-25-2009
Mark <> writes:

> I'm trying to elegantly convert a std_logic_vector(upper downto lower)
> to an integer without sign extension using ieee.numeric_std with upper
> and lower taking on values from 31 to 0 and with upper >= lower. I
> cannot seem to find a syntax that doesn't generate truncation
> warnings, or relies on doing some comparison.
>
> If I use:
>
> i:= to_integer( signed( slv(upper downto lower)));
>
> I'll get sign extension if upper==lower (which I don't want).
>
> To avoid sign extension, I've tried:
>
> i:= to_integer( signed( '0' & slv(upper downto lower)));
>
> That works great until upper=31, and lower=0---leading to a to_signed
> truncation warning (since in this case we're creating a 33-bit vector
> and reducing it to a 32-bit integer).
>
> I could just check if upper==lower, and break the conversion into two
> cases, but I'm wondering if there's a cleaner, more elegant way of
> handling this conversion without warnings.
>
>
>


What's wrong with using unsigned instead of signed?

i:= to_integer( unsigned( slv(upper downto lower)));

- Kenn

--
---------------------------------

 
Reply With Quote
 
 
 
 
Martin Thompson
Guest
Posts: n/a
 
      11-25-2009
Mark <> writes:

> I'm trying to elegantly convert a std_logic_vector(upper downto lower)
> to an integer without sign extension using ieee.numeric_std with upper
> and lower taking on values from 31 to 0 and with upper >= lower. I
> cannot seem to find a syntax that doesn't generate truncation
> warnings, or relies on doing some comparison.
>
> If I use:
>
> i:= to_integer( signed( slv(upper downto lower)));
>
> I'll get sign extension if upper==lower (which I don't want).
>
> To avoid sign extension, I've tried:
>
> i:= to_integer( signed( '0' & slv(upper downto lower)));


I think you might be trying too hard

How about:
i:= to_integer( unsigned( slv(upper downto lower)));

The *unsigned* type is there for doing, erm, unsigned arithmetic and
conversions

That should work for upper==lower as well:

entity testint is
end entity testint;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
architecture a1 of testint is
signal slv : std_logic_vector(1 downto 0) := "10";
signal one,zero : integer;
begin -- architecture a1
check: process is
begin -- process check
one <= to_integer(unsigned(slv(1 downto 1)));
zero <= to_integer(unsigned(slv(0 downto 0)));
wait for 0 ps;
assert one = 1 report "1==1 failure" severity error;
assert zero = 0 report "0==0 failure" severity error;
wait;
end process check;
end architecture a1;

Or did I misunderstand the problem?

Cheers,
Martin

--

TRW Conekt - Consultancy in Engineering, Knowledge and Technology
http://www.conekt.net/electronics.html
 
Reply With Quote
 
Kenn Heinrich
Guest
Posts: n/a
 
      11-25-2009
Kenn Heinrich <> writes:

> Mark <> writes:
>
>> I'm trying to elegantly convert a std_logic_vector(upper downto lower)
>> to an integer without sign extension using ieee.numeric_std with upper
>> and lower taking on values from 31 to 0 and with upper >= lower. I
>> cannot seem to find a syntax that doesn't generate truncation
>> warnings, or relies on doing some comparison.
>>
>> If I use:
>>
>> i:= to_integer( signed( slv(upper downto lower)));
>>
>> I'll get sign extension if upper==lower (which I don't want).
>>
>> To avoid sign extension, I've tried:
>>
>> i:= to_integer( signed( '0' & slv(upper downto lower)));
>>
>> That works great until upper=31, and lower=0---leading to a to_signed
>> truncation warning (since in this case we're creating a 33-bit vector
>> and reducing it to a 32-bit integer).
>>
>> I could just check if upper==lower, and break the conversion into two
>> cases, but I'm wondering if there's a cleaner, more elegant way of
>> handling this conversion without warnings.
>>
>>
>>

>
> What's wrong with using unsigned instead of signed?
>
> i:= to_integer( unsigned( slv(upper downto lower)));
>
> - Kenn


Actually, after a brief re-think, you're sort of hosed in any case.
VHDL only officially defines integers as

type integer is range -2147483648 to 2147483647;

which means you can't represent positive x"FFFFFFFF" = 2^32-1 in
integers to begin with. Implementations *may* support larger but it's
not guaranteed.

- Kenn



--
---------------------------------
Remove NOSPAM from email address.
 
Reply With Quote
 
Mark
Guest
Posts: n/a
 
      11-25-2009
It doesn't matter to me if FFFF_FFFF is treated as -1 or MAX_INT, just
that all the bits are in there. I'd like to get something as C-like
as possible. Unfortunately, VHDL treats unsigned ints (naturals) as a
subtype of integer, and thus are only 31-bits---while C lets you have
32-bit unsigned integers (long)). No problem I thought, I'll just
treat everything as an integer. Unfortunately, doing so in a terse,
warning-free way doesn't seem possible in VHDL.

I'm coming to the conclusion that I'm not going to be able to do a 1-
liner in VHDL without living with warnings. I want my conversions to
be warning free (even if it still works out), so I'm thinking of going
with the following:

lower := c_field_offset;
upper := lower + c_field_size - 1;

if (2**c_field_size-1) > integer'high then
i := to_integer( signed( slv(upper downto lower)));
else
i := to_integer( unsigned( slv(upper downto lower)));
end if;

5-lines instead of 1---but then that's VHDL
 
Reply With Quote
 
Mark
Guest
Posts: n/a
 
      11-25-2009
On Nov 25, 9:30*am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
> On Wed, 25 Nov 2009 06:28:01 -0800 (PST), Mark wrote:
> >I'm trying to elegantly convert a std_logic_vector(upper downto lower)
> >to an integer without sign extension using ieee.numeric_std with upper
> >and lower taking on values from 31 to 0 and with upper >= lower. *I
> >cannot seem to find a syntax that doesn't generate truncation
> >warnings, or relies on doing some comparison.

>
> What's wrong with...
> * i := to_integer(unsigned(slv));
>
> It will of course give you warnings if the MSB of a 32-bit SLV
> is set, because VHDL integer cannot represent anything more
> positive than (2**31)-1. *That's tedious, but a fact of life.
> But it should work fine with any slv with between 1 and 31
> bits, and it will also work with 32-bit SLVs provided their
> MSB is zero.
>
> If you want to use signed() so that 32-bit slv's with the MSB
> set will come out as negative integers (yuck) then yes, you have
> a small problem with 1-bit values. *How about packing to 32 bits
> first, and then doing the conversion?
>
> * i := to_integer(
> * * * * *signed(
> * * * * * * std_logic_vector'(31 downto upper+1 => '0') & slv
> * * * * *)
> * * * *);
>
> This *may* give warnings for the null range when upper=31,
> although it's legal VHDL (I'm pretty sure).
>
> Finally, why not write a custom function instead of trying to
> inline the ghastly mess?
> * function to_uint(v: std_logic_vector) return integer is
> * begin
> * * if v'length = 0 then
> * * * return 0;
> * * elsif v'length = 1 then
> * * * return to_integer(unsigned(v));
> * * else
> * * * return to_integer(signed(v));
> * * end if;
> * end;
>
> The function also provides you with a convenient place
> to report application-specific errors and so forth.
> But most of all it allows you to hide the kruft.
> --
> Jonathan Bromley, Verification Engineer
>
> Verilab *www.THAT_COMPANY.com
> * end;


Gave

i := to_integer( signed( std_logic_vector'(31 downto upper+1 =>
'0') & slv(upper downto lower) ));

a try. Got:

** Warning: [3] test.vhd(25): (vcom-1246) Range 31 downto 32 is
null.

Thanks for the suggestion, though.
 
Reply With Quote
 
Mark
Guest
Posts: n/a
 
      11-25-2009
On Nov 25, 10:36*am, Mark <marmarjohn...@gmail.com> wrote:
> It doesn't matter to me if FFFF_FFFF is treated as -1 or MAX_INT, just
> that all the bits are in there. *I'd like to get something as C-like
> as possible. *Unfortunately, VHDL treats unsigned ints (naturals) as a
> subtype of integer, and thus are only 31-bits---while C lets you have
> 32-bit unsigned integers (long)). *No problem I thought, I'll just
> treat everything as an integer. *Unfortunately, doing so in a terse,
> warning-free way doesn't seem possible in VHDL.
>
> I'm coming to the conclusion that I'm not going to be able to do a 1-
> liner in VHDL without living with warnings. *I want my conversions to
> be warning free (even if it still works out), so I'm thinking of going
> with the following:
>
> * lower := * * * * c_field_offset;
> * upper := lower + c_field_size - 1;
>
> * if (2**c_field_size-1) > integer'high then
> * * i := to_integer( * signed( slv(upper downto lower)));
> * else
> * * i := to_integer( unsigned( slv(upper downto lower)));
> * end if;
>
> 5-lines instead of 1---but then that's VHDL


FYI, the (2**c_field_size - 1) doesn't work as 2**c_field_size itself
needs to be within the range of integers! I finally punted and just
made it : if c_field_size > 31 then ...
 
Reply With Quote
 
Tricky
Guest
Posts: n/a
 
      11-26-2009
On 25 Nov, 16:47, Mark <marmarjohn...@gmail.com> wrote:
> On Nov 25, 9:30*am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
> wrote:
>
>
>
> > On Wed, 25 Nov 2009 06:28:01 -0800 (PST), Mark wrote:
> > >I'm trying to elegantly convert a std_logic_vector(upper downto lower)
> > >to an integer without sign extension using ieee.numeric_std with upper
> > >and lower taking on values from 31 to 0 and with upper >= lower. *I
> > >cannot seem to find a syntax that doesn't generate truncation
> > >warnings, or relies on doing some comparison.

>
> > What's wrong with...
> > * i := to_integer(unsigned(slv));

>
> > It will of course give you warnings if the MSB of a 32-bit SLV
> > is set, because VHDL integer cannot represent anything more
> > positive than (2**31)-1. *That's tedious, but a fact of life.
> > But it should work fine with any slv with between 1 and 31
> > bits, and it will also work with 32-bit SLVs provided their
> > MSB is zero.

>
> > If you want to use signed() so that 32-bit slv's with the MSB
> > set will come out as negative integers (yuck) then yes, you have
> > a small problem with 1-bit values. *How about packing to 32 bits
> > first, and then doing the conversion?

>
> > * i := to_integer(
> > * * * * *signed(
> > * * * * * * std_logic_vector'(31 downto upper+1 => '0') & slv
> > * * * * *)
> > * * * *);

>
> > This *may* give warnings for the null range when upper=31,
> > although it's legal VHDL (I'm pretty sure).

>
> > Finally, why not write a custom function instead of trying to
> > inline the ghastly mess?
> > * function to_uint(v: std_logic_vector) return integer is
> > * begin
> > * * if v'length = 0 then
> > * * * return 0;
> > * * elsif v'length = 1 then
> > * * * return to_integer(unsigned(v));
> > * * else
> > * * * return to_integer(signed(v));
> > * * end if;
> > * end;

>
> > The function also provides you with a convenient place
> > to report application-specific errors and so forth.
> > But most of all it allows you to hide the kruft.
> > --
> > Jonathan Bromley, Verification Engineer

>
> > Verilab *www.THAT_COMPANY.com
> > * end;

>
> Gave
>
> * *i := to_integer( signed( std_logic_vector'(31 downto upper+1 =>
> '0') & slv(upper downto lower) ));
>
> a try. *Got:
>
> * *** Warning: [3] test.vhd(25): (vcom-1246) Range 31 downto 32 is
> null.
>
> Thanks for the suggestion, though.


Why do you have to use the integer type? why cant you just stick with
signed/unsigned? Afaik, you can still do all the same arithmatic on
signed/unsigned, but you have no bit width problems.
 
Reply With Quote
 
Jan Decaluwe
Guest
Posts: n/a
 
      11-26-2009
Tricky wrote:
> On 25 Nov, 16:47, Mark <marmarjohn...@gmail.com> wrote:
>> On Nov 25, 9:30 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
>> wrote:
>>
>>
>>
>>> On Wed, 25 Nov 2009 06:28:01 -0800 (PST), Mark wrote:
>>>> I'm trying to elegantly convert a std_logic_vector(upper downto lower)
>>>> to an integer without sign extension using ieee.numeric_std with upper
>>>> and lower taking on values from 31 to 0 and with upper >= lower. I
>>>> cannot seem to find a syntax that doesn't generate truncation
>>>> warnings, or relies on doing some comparison.
>>> What's wrong with...
>>> i := to_integer(unsigned(slv));
>>> It will of course give you warnings if the MSB of a 32-bit SLV
>>> is set, because VHDL integer cannot represent anything more
>>> positive than (2**31)-1. That's tedious, but a fact of life.
>>> But it should work fine with any slv with between 1 and 31
>>> bits, and it will also work with 32-bit SLVs provided their
>>> MSB is zero.
>>> If you want to use signed() so that 32-bit slv's with the MSB
>>> set will come out as negative integers (yuck) then yes, you have
>>> a small problem with 1-bit values. How about packing to 32 bits
>>> first, and then doing the conversion?
>>> i := to_integer(
>>> signed(
>>> std_logic_vector'(31 downto upper+1 => '0') & slv
>>> )
>>> );
>>> This *may* give warnings for the null range when upper=31,
>>> although it's legal VHDL (I'm pretty sure).
>>> Finally, why not write a custom function instead of trying to
>>> inline the ghastly mess?
>>> function to_uint(v: std_logic_vector) return integer is
>>> begin
>>> if v'length = 0 then
>>> return 0;
>>> elsif v'length = 1 then
>>> return to_integer(unsigned(v));
>>> else
>>> return to_integer(signed(v));
>>> end if;
>>> end;
>>> The function also provides you with a convenient place
>>> to report application-specific errors and so forth.
>>> But most of all it allows you to hide the kruft.
>>> --
>>> Jonathan Bromley, Verification Engineer
>>> Verilab www.THAT_COMPANY.com
>>> end;

>> Gave
>>
>> i := to_integer( signed( std_logic_vector'(31 downto upper+1 =>
>> '0') & slv(upper downto lower) ));
>>
>> a try. Got:
>>
>> ** Warning: [3] test.vhd(25): (vcom-1246) Range 31 downto 32 is
>> null.
>>
>> Thanks for the suggestion, though.

>
> Why do you have to use the integer type? why cant you just stick with
> signed/unsigned? Afaik, you can still do all the same arithmatic on
> signed/unsigned, but you have no bit width problems.


That is not true: with signed/unsigned you are forced to
deal with bit widths and resizes explicitly, unlike integer.

Given all the pain that comes out of discussions such as this one,
I'd like to point out that with MyHDL, I think I have solved these issues.
In MyHDL, you can use a (constrained) integer with arbitrary sizes,
and the convertor to VHDL will deal with the low-level issues for you.

See:
http://www.myhdl.org/doku.php/why#yo...sion_functions

Background:
http://www.jandecaluwe.com/hdldesign/counting.html

Jan

--
Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com
Python as a HDL: http://www.myhdl.org
VHDL development, the modern way: http://www.sigasi.com
Analog design automation: http://www.mephisto-da.com
World-class digital design: http://www.easics.com
 
Reply With Quote
 
Gerhard Hoffmann
Guest
Posts: n/a
 
      11-26-2009
On Wed, 25 Nov 2009 23:25:41 +0100, Jonathan Bromley <> wrote:


>Yes, I know it's a damned nuisance, but that's what the
>language standard says.


Is there somewhere a standard or near-standard package
for things like u_int64 or s_int128?

Writing a testbed for a 64 bit CPU is a royal pain, and
even if these long ints were composed from the usual 31.9 bit ints,
this should simulate much faster than SLVs, where each and
every single bit has to be kissed individually.


regards, Gerhard

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Converting integer to std_logic_vector Rockerboy VHDL 5 12-10-2007 07:59 PM
inout std_logic_vector to array of std_logic_vector of generic length conversion... Thomas Rouam VHDL 6 11-09-2007 11:49 AM
Automatic sign-up and sign-in across different domains without cookies? Jimmy ASP .Net 1 11-21-2006 04:41 PM
Converting std_logic_vector to integer skilambi@gmail.com VHDL 3 04-30-2006 07:37 PM
converting std_logic_vector to integer vedpsingh@gmail.com VHDL 5 08-16-2005 10:03 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57