Signed Adder without overflow

Discussion in 'VHDL' started by Nemesis, May 24, 2005.

  1. Nemesis

    Nemesis Guest

    Hi all,
    I have to implement a 24 bit signed adder. I have two 2's
    complement numbers on 24, and I'd like to get their sum on 25 bit signed
    (2's complement). I already tried the Xilinx IP Adder core, but I'd like
    to implement this adder in VHDL.

    I wrote this module:

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

    entity adder24 is
    port (
    A : in STD_LOGIC_VECTOR(23 downto 0);
    B : in STD_LOGIC_VECTOR(23 downto 0);
    CLK : in STD_LOGIC;
    RESET : in STD_LOGIC;
    OUTPUT : out STD_LOGIC_VECTOR(24 downto 0)
    );
    end adder24;

    architecture Behavioral of adder24 is
    begin
    ----------------------------------------------------------------
    process (CLK,RESET)
    variable A_INT : SIGNED (23 downto 0);
    variable B_INT : SIGNED (23 downto 0);
    variable OUTPUT_VAR : SIGNED (24 downto 0);
    begin
    if RESET='1' then
    OUTPUT <= "0000000000000000000000000";
    elsif CLK='1' and CLK'event then
    A_INT :=SIGNED(A);
    B_INT :=SIGNED(B);
    OUTPUT_VAR := A_INT + B_INT;
    OUTPUT <= STD_LOGIC_VECTOR(OUTPUT_VAR);
    end if;
    end process;
    ----------------------------------------------------------------
    end Behavioral;
    **********************************************************************

    I'm able to synthesize it (I get a warning on the OUTPUT_VAR size) but
    modelsim returns me this error:

    Length of actual is 24. Length of expected is 25.

    so I can't simulate it.

    How can I write a 24bit adder with a 25bit output, and with input and
    output signed?

    --
    Proofread carefully to see if you any words out.

    |\ | |HomePage : http://nem01.altervista.org
    | \|emesis |XPN (my nr): http://xpn.altervista.org
     
    Nemesis, May 24, 2005
    #1
    1. Advertising

  2. Changes you should made:

    variable A_INT : SIGNED (24 downto 0);
    variable B_INT : SIGNED (24 downto 0);
    variable OUTPUT_VAR : SIGNED (24 downto 0);
    begin
    if RESET='1' then
    OUTPUT <= "0000000000000000000000000";
    elsif CLK='1' and CLK'event then
    A_INT :=SIGNED(A(23) & A);
    B_INT :=SIGNED(B(23) & B);
    OUTPUT_VAR := A_INT + B_INT;

    A(23) & A is to sign-extend A while keeping A value unchanged.

    Weng
     
    Weng Tianxiang, May 24, 2005
    #2
    1. Advertising

  3. Nemesis

    Nemesis Guest

    Mentre io pensavo ad una intro simpatica "Weng Tianxiang" scriveva:

    > Changes you should made:
    >
    > variable A_INT : SIGNED (24 downto 0);
    > variable B_INT : SIGNED (24 downto 0);
    > variable OUTPUT_VAR : SIGNED (24 downto 0);
    > begin
    > if RESET='1' then
    > OUTPUT <= "0000000000000000000000000";
    > elsif CLK='1' and CLK'event then
    > A_INT :=SIGNED(A(23) & A);
    > B_INT :=SIGNED(B(23) & B);
    > OUTPUT_VAR := A_INT + B_INT;
    >
    > A(23) & A is to sign-extend A while keeping A value unchanged.



    Thank you very much, I just tried your code and it seems to work
    correctly. Tomorrow I'll test it better.

    --
    History is written by the survivors.

    |\ | |HomePage : http://nem01.altervista.org
    | \|emesis |XPN (my nr): http://xpn.altervista.org
     
    Nemesis, May 24, 2005
    #3
  4. Nemesis

    Andy Peters Guest

    Nemesis wrote:
    > Hi all,
    > I have to implement a 24 bit signed adder. I have two 2's
    > complement numbers on 24, and I'd like to get their sum on 25 bit signed
    > (2's complement). I already tried the Xilinx IP Adder core, but I'd like
    > to implement this adder in VHDL.
    >
    > I wrote this module:
    >
    > **********************************************************************
    > library IEEE;
    > use IEEE.STD_LOGIC_1164.ALL;
    > use IEEE.STD_LOGIC_ARITH.ALL;
    > use IEEE.STD_LOGIC_UNSIGNED.ALL;
    > use IEEE.STD_LOGIC_SIGNED.ALL;


    DON'T use std_logic_arith, and especially don't use both
    std_logic_unsigned and std_logic_signed at the same time! Use
    numeric_std instead.

    > entity adder24 is
    > port (
    > A : in STD_LOGIC_VECTOR(23 downto 0);
    > B : in STD_LOGIC_VECTOR(23 downto 0);
    > CLK : in STD_LOGIC;
    > RESET : in STD_LOGIC;
    > OUTPUT : out STD_LOGIC_VECTOR(24 downto 0)
    > );
    > end adder24;
    >
    > architecture Behavioral of adder24 is
    > begin
    > ----------------------------------------------------------------
    > process (CLK,RESET)
    > variable A_INT : SIGNED (23 downto 0);
    > variable B_INT : SIGNED (23 downto 0);
    > variable OUTPUT_VAR : SIGNED (24 downto 0);
    > begin
    > if RESET='1' then
    > OUTPUT <= "0000000000000000000000000";
    > elsif CLK='1' and CLK'event then
    > A_INT :=SIGNED(A);
    > B_INT :=SIGNED(B);
    > OUTPUT_VAR := A_INT + B_INT;
    > OUTPUT <= STD_LOGIC_VECTOR(OUTPUT_VAR);
    > end if;
    > end process;
    > ----------------------------------------------------------------
    > end Behavioral;
    > **********************************************************************
    >
    > I'm able to synthesize it (I get a warning on the OUTPUT_VAR size) but
    > modelsim returns me this error:
    >
    > Length of actual is 24. Length of expected is 25.
    >
    > so I can't simulate it.
    >
    > How can I write a 24bit adder with a 25bit output, and with input and
    > output signed?


    Simply sign-extend A and B:

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

    entity adder24 is
    port (
    A : in STD_LOGIC_VECTOR(23 downto 0);
    B : in STD_LOGIC_VECTOR(23 downto 0);
    CLK : in STD_LOGIC;
    RESET : in STD_LOGIC;
    OUTPUT : out STD_LOGIC_VECTOR(24 downto 0));
    end entity adder24;

    architecture math of adder24 is

    adder : process (CLK, RESET) is
    variable a_s : signed(A'high+1 downto 0);
    variable b_s : signed(B'high+1 downto 0);
    variable sum : signed(A'high+1 downto 0);
    begin
    if RESET = '1' then
    OUTPUT <= (others => '0');
    elsif rising_edge (CLK) then
    a_s := resize(signed(A), a_s'length);
    b_s := resize(signed(B), b_s'length);
    sum := a_s + b_s;
    OUTPUT <= std_logic_vector(sum);
    end if;
    end process adder;
    end architecture math;
     
    Andy Peters, May 24, 2005
    #4
  5. Nemesis

    Nemesis Guest

    Mentre io pensavo ad una intro simpatica "Andy Peters" scriveva:

    > DON'T use std_logic_arith, and especially don't use both
    > std_logic_unsigned and std_logic_signed at the same time! Use
    > numeric_std instead.


    I tried everything ;-)
    However with your hint on using numeric_std I found an interesting
    web-site that explains the differences betwen
    numeric_std, std_logic_arith ... and so on.

    > Simply sign-extend A and B:

    [cut]

    Thanks, I liked your solution very much.

    --
    I said "NO" to drugs... but they just WOULDN'T listen.

    |\ | |HomePage : http://nem01.altervista.org
    | \|emesis |XPN (my nr): http://xpn.altervista.org
     
    Nemesis, May 25, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Zaki
    Replies:
    2
    Views:
    6,669
    Egbert Molenkamp
    Jun 30, 2004
  2. Rune Christensen
    Replies:
    4
    Views:
    10,029
    David R Brooks
    Jan 22, 2005
  3. JKop

    signed int overflow

    JKop, Sep 20, 2004, in forum: C++
    Replies:
    45
    Views:
    1,694
    Greg Comeau
    Sep 24, 2004
  4. hexler
    Replies:
    1
    Views:
    2,546
    martin.wahlstedt
    Apr 16, 2007
  5. blckisle

    overflow of adder in VHDL

    blckisle, May 3, 2008, in forum: VHDL
    Replies:
    1
    Views:
    1,072
    blckisle
    May 3, 2008
Loading...

Share This Page