Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] addition of signed in vhdl

Status
Not open for further replies.

goldi697

Newbie level 5
Joined
Jun 1, 2012
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,345
hello,

in my code i am using (1 10 5) word length format, 1 bit is for sign, 10 for integer and 5 for fraction, i want to add two 16 bit numbers in this format, means as per the sign bit addition or subtraction should be performed and final result should also in this format. please help me for that addition. i am doing addition by using if else, every time i check sign then i will perform 2's comp then again i m checking for magnitude to decide the sign of final result, its working but at the time of sythesis it map 10 adder instead of one because i m using if else condition.
 

whats wrong with:

a <= b + c;

i m using input in std_logic_vector
my all of calculation is in fixed point.
if a = 1001 and b = 0110
c = a + b
c = 1111
wrong
because here a = -1
and b = +6
c = 5

but here o/p is -7 which is wrong
 

1001 -7, not -1. So -7 + 6 = -1 = 1111
Your format is not 2s compliment. fixed point can still be 2s compliment.

you didnt post your code, so we cannot tell whats wrong.
 

1001 -7, not -1. So -7 + 6 = -1 = 1111
Your format is not 2s compliment. fixed point can still be 2s compliment.

you didnt post your code, so we cannot tell whats wrong.


here i m taking signed bit separate. my inputs are not 2,s complemented,
here 100111 means -7 , first bit only to decide sign, and remaing to decide magnitude, in unsigned format.


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;




procedure addition (variable a1,b1: in std_logic_vector(15 downto 0);
variable c1: out std_logic_vector(15 downto 0)) is
variable te1,te2,te3,te11,te22:std_logic_vector(14 downto 0);
variable te4 :std_logic_vector(15 downto 0);
variable s_a,s_b:std_logic;

begin
s_a := a1(15);
s_b := b1(15);
te11 := a1(14 downto 0);
te22 := b1(14 downto 0);

if (s_a = '1' ) then
if (s_b = '1' ) then
te3 := te11+te22;
te4 := '1' & te3;
else
if (te11<te22)then
te1 := (not(te11)) + 1;
te2 := te1 + te22;
te4 :='0' & te2;
elsif (te11>te22) then
te1 := (not(te22)) + 1;
te2 := te1 + te11;
te4 :='1' & te2;
elsif (te11=te22) then
te4 :="0000000000000000";
end if;
end if;
else
if (s_b = '0' ) then
te3 := te11+te22;
te4 := '0' & te3;
else
if (te11>te22) then
te1 := (not(te22)) + 1;
te2 := te11 + te1;
te4 := '0' & te2;
elsif(te11<te22) then
te1 := (not(te11)) + 1;
te2 := te22 + te1;
te4 := '1' & te2;
elsif (te11=te22) then
te4 :="0000000000000000";
end if;
end if;
end if;

if (te4 = "1000000000000000") then
te4 := "0000000000000000";
end if;
c1:=te4;


end addition;
 

I recommend you switch to ieee.numeric_std library for arithmetic and use signed type for signed operations and unsigned for unsigned operations.
 

hello,

in my code i am using (1 10 5) word length format, 1 bit is for sign, 10 for integer and 5 for fraction, i want to add two 16 bit numbers in this format, means as per the sign bit addition or subtraction should be performed and final result should also in this format. please help me for that addition. i am doing addition by using if else, every time i check sign then i will perform 2's comp then again i m checking for magnitude to decide the sign of final result, its working but at the time of sythesis it map 10 adder instead of one because i m using if else condition.

There is already a fixed point library of code written, use that instead: http://www.eda.org/fphdl/

For what you mentioned above, you would declare the signals something like this...
signal xyz: sfixed(10 downto -5);

And then you would simply add the signals:

sum <= xyz + abc;

Don't re-invent the wheel, use already existing well tested ones instead.

Kevin Jennings
 

I understand, that sign/magnitude representation of in- and output signals is required for some reason. The behaviour in case of overflow should be exactly specified, as far as I see, they are not handled explicitely in your code.

While two's complement signed arithmetic is supported by the standard VHDL libraries, sign/magnitude isn't and needs to be emulated somehow. The effort will be higher as with basic two's complement anyway, with or without handling of overflows respectively saturation logic.

Regarding fixed point numbers, you don't need to consider it for pure add/subtract operations. ieee.fixed_pkg can be useful to implement saturation as overflow handling, but because it doesn't support sign/magnitude, it probably isn't for the present problem.


My somewhat more compact suggestion for the addition of sign/magnitude signed format based on regular signed arithmetic. It uses an auxilary bit to sense overflows and applies saturation.

Code:
variable a,b,c: signed (16 downto 0);
begin
if a1(15) = '0' then
  a := signed("00"& a1(14 downto 0));
else  
  a := -signed("00"& a1(14 downto 0));
end if;  
if b1(15) = '0' then
  b := signed("00"& b1(14 downto 0));
else  
  b := -signed("00"& b1(14 downto 0));
end if;
c := a + b;
if c <= -2**15 then
  c1 := x"ffff";
elsif c < 0 then
  c := -c;
  c1 := '1' & std_logic_vector(c(14 downto 0));
elsif c >= 2**15 then
  c1 := '0' & std_logic_vector(c(14 downto 0));
else
  c1 := x"7fff";
end if;       
end;
 

I understand, that sign/magnitude representation of in- and output signals is required for some reason. The behaviour in case of overflow should be exactly specified, as far as I see, they are not handled explicitely in your code.

While two's complement signed arithmetic is supported by the standard VHDL libraries, sign/magnitude isn't and needs to be emulated somehow. The effort will be higher as with basic two's complement anyway, with or without handling of overflows respectively saturation logic.

Regarding fixed point numbers, you don't need to consider it for pure add/subtract operations. ieee.fixed_pkg can be useful to implement saturation as overflow handling, but because it doesn't support sign/magnitude, it probably isn't for the present problem.


My somewhat more compact suggestion for the addition of sign/magnitude signed format based on regular signed arithmetic. It uses an auxilary bit to sense overflows and applies saturation.



thax for the help.......

this code is working but it required much hardware and delay is also more

approximate 11 ns

i m using this as adder for my proj..............affecting overall speed


suggest me technique to improove hardware utilization for this code
 

I fear, both codes are demonstrating more or less the ineffective operation of sign/magnitude arithmetic. I didn't yet hear a clear motivation why you are using it, also the overflow handling point should be clarified.
 

I fear, both codes are demonstrating more or less the ineffective operation of sign/magnitude arithmetic. I didn't yet hear a clear motivation why you are using it, also the overflow handling point should be clarified.




in my project i am using 30 multiplier and 46 adders, and the multiplier coefficients are negative.
for example
a = b + const*(c+d);

all values having 5 bit fraction;
const = -1.8253;

to implement this equation i need to take (1 10 5) format because by using 2's compl method multiplier get saturated.
 

in my project i am using 30 multiplier and 46 adders, and the multiplier coefficients are negative.
for example
a = b + const*(c+d);

all values having 5 bit fraction;
const = -1.8253;

to implement this equation i need to take (1 10 5) format because by using 2's compl method multiplier get saturated.

Your statement makes no sense. Math is math. You can choose (unwisely) to implement it in some form of signed magnitude format and run into the problems you're facing as well as others that you haven't even considered to this point. Or you can choose more wisely to use twos compliment representation and use the standard fixed point VHDL package that I referenced earlier.

Ask yourself a simple question: If 2's compl method multiplier get saturated as you said, then why is it that you think your signed magnitude format won't have the same issue?

Kevin Jennings
 

Your statement makes no sense. Math is math. You can choose (unwisely) to implement it in some form of signed magnitude format and run into the problems you're facing as well as others that you haven't even considered to this point. Or you can choose more wisely to use twos compliment representation and use the standard fixed point VHDL package that I referenced earlier.

Ask yourself a simple question: If 2's compl method multiplier get saturated as you said, then why is it that you think your signed magnitude format won't have the same issue?

Kevin Jennings

i have checked............for example in 16 bit format to represent -3 i have to right "1111111111111110" thats the value i have to multiply with 512 and wants to save it again in 16 bit register............

u will find value get saturated...

but in my formate -3 is "1000000000000011" now if i multiply it would be -(512*3) means -(000000000000011*1000000000)

here no saturation.........!!
 

Without explicite handling, overflow in arithmetic won't cause saturation but roll over to arbitrary wrong results. The only "advantage" of sign/magntude format is that the sign doesn't change, magnitude rolls over to zero instead, still causing nasty effects.

Apart from the principle properties of different number systems, it's a simple fact that all arithmetic HDL libraries are working with two's complement to represent signed numbers and all FPGA vendor numeric hard- and soft IP is using it.
 

i have checked............for example in 16 bit format to represent -3 i have to right "1111111111111110" thats the value i have to multiply with 512 and wants to save it again in 16 bit register............

u will find value get saturated...
-1536 can be represented by a 16b number.
you will have x"FFFD" * x"0200" = x"FFFFFA00". if the lower 16b are kept, this is x"FA00". invert = x"05FF". add 1 = x"0600"

(also, -3 is FFFD)
 

i have checked............for example in 16 bit format to represent -3 i have to right "1111111111111110" thats the value i have to multiply with 512 and wants to save it again in 16 bit register............

u will find value get saturated...

but in my formate -3 is "1000000000000011" now if i multiply it would be -(512*3) means -(000000000000011*1000000000)

here no saturation.........!!

Well, you should check again, because you're incorrect. Twos complement and the fixed point package handle the math quite well. But don't take my word for it, believe the code and actual results which are posted below. You can modify it to your heart's content, what it demonstrates is that 512 multiplied by -3 is equal to -1536 where all the numbers are represented as 16 bit numbers with 5 of those bits to the right of the binary point.

Code:
library ieee_proposed;
use ieee_proposed.fixed_pkg.all;
use ieee_proposed.math_utility_pkg.all;

entity foo is
end foo;

architecture RTL of foo is
    signal a:       sfixed(11 downto -5);
    signal b:       sfixed(11 downto -5);
    signal prod:    sfixed(11 downto -5);
begin
    a       <= to_sfixed(-3.0, a'left, a'right);
    b       <= to_sfixed(512, a'left, a'right);
    prod    <= resize(a*b, prod'left, prod'right);

--synthesis translate_off
    checker : block
        signal a_real:      real;
        signal b_real:      real;
        signal prod_real:   real;
    begin
        a_real      <= to_real(a);
        b_real      <= to_real(b);
        prod_real   <= to_real(prod);

        process(a_real, b_real, prod_real)
        begin
            report  "a=" & real'image(a_real) & LF &
                    "b=" & real'image(b_real) & LF &
                    "prod=" & real'image(prod_real);
        end process;
    end block checker;
--synthesis translate_on
end RTL;

The simulation result transcript is below...no errors...end of story, it works.

# vsim foo
# // ModelSim PE 6.4 Jun 18 2008
# Loading std.standard
# Loading std.textio(body)
# Loading ieee.std_logic_1164(body)
# Loading ieee.numeric_std(body)
# Loading ieee_proposed.math_utility_pkg
# Loading ieee.math_real(body)
# Loading ieee_proposed.fixed_pkg(body)
# Loading work.foo(rtl)
# ** Note: a=-1.000000e+308
# b=-1.000000e+308
# prod=-1.000000e+308
# Time: 0 ps Iteration: 0 Instance: /foo/checker
# ** Note: a=0.000000e+000
# b=0.000000e+000
# prod=0.000000e+000
# Time: 0 ps Iteration: 1 Instance: /foo/checker
# ** Note: a=-3.000000e+000
# b=5.120000e+002
# prod=0.000000e+000
# Time: 0 ps Iteration: 2 Instance: /foo/checker
# ** Note: a=-3.000000e+000
# b=5.120000e+002
# prod=-1.536000e+003
# Time: 0 ps Iteration: 3 Instance: /foo/checker


Kevin Jennings
 

Well, you should check again, because you're incorrect. Twos complement and the fixed point package handle the math quite well. But don't take my word for it, believe the code and actual results which are posted below. You can modify it to your heart's content, what it demonstrates is that 512 multiplied by -3 is equal to -1536 where all the numbers are represented as 16 bit numbers with 5 of those bits to the right of the binary point.

Code:
library ieee_proposed;
use ieee_proposed.fixed_pkg.all;
use ieee_proposed.math_utility_pkg.all;

entity foo is
end foo;

architecture RTL of foo is
    signal a:       sfixed(11 downto -5);
    signal b:       sfixed(11 downto -5);
    signal prod:    sfixed(11 downto -5);
begin
    a       <= to_sfixed(-3.0, a'left, a'right);
    b       <= to_sfixed(512, a'left, a'right);
    prod    <= resize(a*b, prod'left, prod'right);

--synthesis translate_off
    checker : block
        signal a_real:      real;
        signal b_real:      real;
        signal prod_real:   real;
    begin
        a_real      <= to_real(a);
        b_real      <= to_real(b);
        prod_real   <= to_real(prod);

        process(a_real, b_real, prod_real)
        begin
            report  "a=" & real'image(a_real) & LF &
                    "b=" & real'image(b_real) & LF &
                    "prod=" & real'image(prod_real);
        end process;
    end block checker;
--synthesis translate_on
end RTL;

The simulation result transcript is below...no errors...end of story, it works.

# vsim foo
# // ModelSim PE 6.4 Jun 18 2008
# Loading std.standard
# Loading std.textio(body)
# Loading ieee.std_logic_1164(body)
# Loading ieee.numeric_std(body)
# Loading ieee_proposed.math_utility_pkg
# Loading ieee.math_real(body)
# Loading ieee_proposed.fixed_pkg(body)
# Loading work.foo(rtl)
# ** Note: a=-1.000000e+308
# b=-1.000000e+308
# prod=-1.000000e+308
# Time: 0 ps Iteration: 0 Instance: /foo/checker
# ** Note: a=0.000000e+000
# b=0.000000e+000
# prod=0.000000e+000
# Time: 0 ps Iteration: 1 Instance: /foo/checker
# ** Note: a=-3.000000e+000
# b=5.120000e+002
# prod=0.000000e+000
# Time: 0 ps Iteration: 2 Instance: /foo/checker
# ** Note: a=-3.000000e+000
# b=5.120000e+002
# prod=-1.536000e+003
# Time: 0 ps Iteration: 3 Instance: /foo/checker


Kevin Jennings





where i will get library ieee_prposed
i have downloaded from the given link but its not working.......!!
text me the path to download that libraray
 

where i will get library ieee_prposed
i have downloaded from the given link but its not working.......!!
text me the path to download that libraray

The User's Guide is fairly clear and is in the link that I posted.

- Create a new library called ieee_proposed in your simulator
- Add the two files you need to your project. With the simulator GUI, change the properties to say that they are to be compiled into the ieee_proposed library
- Compile and run.

If you have problems consider making a more obvious statement about what is not working. Simply saying "i have downloaded from the given link but its not working.......!!" is rather pointless since only you know what "it's not working" means, nobody else does.


Kevin Jennings
 

I recommend you switch to ieee.numeric_std library for arithmetic and use signed type for signed operations and unsigned for unsigned operations.



Thax for the suggestion, by changing the libraray and data type i got same result as previous architecture with exellent hardware utilization.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top