More signed/unsigned arithmetic craziness 
Author Message
 More signed/unsigned arithmetic craziness

Hello again.

        Well, I hope I'm slightly more informed this time. After
working with an unsigned implementation of a linear interpolator, I
realized I needed to use two's compliment arithmetic for the data. The
problem with this is that one of the operands in the algorithm I'm
implementing in VHDL is unsigned. I've also converted all of my code
over to the numeric_std library, but I can't do something like:

  (pa_i + interp) * (pb_i - pa_i)

when pa_i and pb_i are signed 24-bit values and interp is a 16-bit
unsigned value. I've tried the following things to get around this
with P1076.3:

- using the TO_SIGNED function. Unfortunately, upon browsing the
source code for the numeric_std package, there's only one
implementation of this function which converts from integers to the
signed format in numeric_std.

- Direct assignment. I tried creating a 24-bit signed signal, then
assigning a padded version of the 16-bit unsigned signal to the signed
signal like so:

signal interp_temp : signed(23 downto 0);

...

interp_temp <= "00000000" & interp_i;

Additionally, the version of numeric_std I have doesn't have an
overloaded operator for adding signed and unsigned quantities (for
good reason IMHO), so how do I do this?

Regards,

Joe



Wed, 15 Jun 2005 07:01:29 GMT  
 More signed/unsigned arithmetic craziness
Try extending interp to 17 bits and fixing the upper bit to '0' so it is
positive, and call the signal SIGNED.
Only an idea, Niv.


Quote:
> Hello again.

> Well, I hope I'm slightly more informed this time. After
> working with an unsigned implementation of a linear interpolator, I
> realized I needed to use two's compliment arithmetic for the data. The
> problem with this is that one of the operands in the algorithm I'm
> implementing in VHDL is unsigned. I've also converted all of my code
> over to the numeric_std library, but I can't do something like:

>   (pa_i + interp) * (pb_i - pa_i)

> when pa_i and pb_i are signed 24-bit values and interp is a 16-bit
> unsigned value. I've tried the following things to get around this
> with P1076.3:

> - using the TO_SIGNED function. Unfortunately, upon browsing the
> source code for the numeric_std package, there's only one
> implementation of this function which converts from integers to the
> signed format in numeric_std.

> - Direct assignment. I tried creating a 24-bit signed signal, then
> assigning a padded version of the 16-bit unsigned signal to the signed
> signal like so:

> signal interp_temp : signed(23 downto 0);

> ...

> interp_temp <= "00000000" & interp_i;

> Additionally, the version of numeric_std I have doesn't have an
> overloaded operator for adding signed and unsigned quantities (for
> good reason IMHO), so how do I do this?

> Regards,

> Joe



Wed, 15 Jun 2005 18:24:42 GMT  
 More signed/unsigned arithmetic craziness

Quote:
>> I can't do something like:

>>   (pa_i + interp) * (pb_i - pa_i)

>> when pa_i and pb_i are signed 24-bit values and interp is a 16-bit
>> unsigned value.
>Try extending interp to 17 bits and fixing the upper bit to '0' so it is
>positive, and call the signal SIGNED.

Yes, this is basically right.

SIGNED and UNSIGNED are both arrays of STD_LOGIC indexed by NATURAL.
Therefore they are "closely related types" and it's easy to cast
one to another:

  -- Make a SIGNED variable one bit wider than 'interp':
  variable interp_signed: SIGNED (interp'LENGTH downto 0);

  -- Now copy 'interp' into it:
  interp_signed := SIGNED('0' & interp);

  -- Now you can do the arithmetic:
  result_signed := interp_signed * pa_i;

Don't forget that the number of bits in the result of your
SIGNED * SIGNED multiplication is the sum of the number of
bits in the two operands, so in your case the product will
be 17+24=41 bits wide, so you'll need a SIGNED(40 downto 0)
to store it.  Then, I guess, you'll prune off the bits you
don't need.  Don't forget to check for overflow.

Overflow checks are quite easy.  If you are intending to
throw away more-significant bits, check that all the bits you
intend to throw away are the same value as the most significant
bit of the shortened signed result.  If not, you have an
overflow condition.

HTH
--
Jonathan Bromley



Wed, 15 Jun 2005 19:29:25 GMT  
 More signed/unsigned arithmetic craziness
Borrowing a little from the "other joe's" code:

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

entity test is end test;
architecture behave of test is
   signal interp_o   : signed(47 downto 0);  --Size = Sum of Size of args
   signal pa_i, pb_i : signed(23 downto 0);
   signal interp_i   : unsigned(15 downto 0);

begin

   -- type casting signed( ...) can be used to convert
   -- closely related types with common indices.
   -- Hence, these can be used to convert between:
   -- signed, unsigned, and std_logic_vector
   -- For unsigned to signed, the '0' is added to ensure
   -- the MSB = Left most indice = Sign Bit = 0
   interp_o <= (pa_i + signed('0' & interp_i)) * (pb_i - pa_i);

end behave;

Cheers,
Jim

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis

SynthWorks Design Inc.           http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Quote:

> Hello again.

>    Well, I hope I'm slightly more informed this time. After
> working with an unsigned implementation of a linear interpolator, I
> realized I needed to use two's compliment arithmetic for the data. The
> problem with this is that one of the operands in the algorithm I'm
> implementing in VHDL is unsigned. I've also converted all of my code
> over to the numeric_std library, but I can't do something like:

>   (pa_i + interp) * (pb_i - pa_i)

> when pa_i and pb_i are signed 24-bit values and interp is a 16-bit
> unsigned value. I've tried the following things to get around this
> with P1076.3:

> - using the TO_SIGNED function. Unfortunately, upon browsing the
> source code for the numeric_std package, there's only one
> implementation of this function which converts from integers to the
> signed format in numeric_std.

> - Direct assignment. I tried creating a 24-bit signed signal, then
> assigning a padded version of the 16-bit unsigned signal to the signed
> signal like so:

> signal interp_temp : signed(23 downto 0);

> ...

> interp_temp <= "00000000" & interp_i;

> Additionally, the version of numeric_std I have doesn't have an
> overloaded operator for adding signed and unsigned quantities (for
> good reason IMHO), so how do I do this?

> Regards,

> Joe

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis

SynthWorks Design Inc.           http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



Sun, 19 Jun 2005 01:05:38 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. unsigned word to signed word in RB

2. Signed/Unsigned Documentation CW2.002

3. signed,unsigned in verilog?!

4. Signed/Unsigned Operations for OVI 2.0

5. Signed and unsigned

6. Signed / Unsigned question.

7. Signed and Unsigned numbers?

8. unsigned ,signed how does it works

9. Numeric STD Signed/Unsigned/Extra

10. signed/unsigned v.s. integer

11. conversion between signed and unsigned using numeric_std

12. 32-bit signed, unsigned and integers and overflows

 

 
Powered by phpBB® Forum Software