Numeric variable type

Discussion in 'VHDL' started by Bibi69, Feb 1, 2007.

  1. Bibi69

    Bibi69 Guest

    Hi,
    I've a question concerning variable types :
    I want to add two 4 bits signed values and a one-bit value.
    What seems to be the most efficient method to me is to use a 4-bit adder
    with a carry-in bit.
    If I write
    i1 : in std_logic_vector(3 downto 0);
    i2 : in std_logic_vector(3 downto 0);
    ci : in std_logic;
    o : out std_logic_vector(3 downto 0);

    o <= i1+i2+ci;

    the synthesis (with xilinx ise 8.1) is ok but people have said me it's
    bad to add std_logic_vector and std_logic.

    When I use signed and bit types, the synthesizer tells '+' isn't a
    correct operator...

    Does someone have a piece of advice on what I should do ?

    Moreover I want to have three such adders making a tree structure.
    If I write :
    i1 : in std_logic_vector(3 downto 0);
    i2 : in std_logic_vector(3 downto 0);
    i3 : in std_logic_vector(3 downto 0);
    i4 : in std_logic_vector(3 downto 0);
    c1 : in std_logic;
    c2 : in std_logic;
    c3 : in std_logic;
    o : out std_logic_vector(3 downto 0);

    I tried o <= (i1+i2+c1)+(i3+i4+c2)+c3;
    That doesn't give an efficient result, no adder tree.
    To have a good tree structure I have to write :
    signal t1 : std_logic_vector(3 downto 0);
    signal t2 : std_logic_vector(3 downto 0);

    t1 <= i1+i2+c1;
    t2 <= i3+i4+c2;
    o <= t1+t2+c3;

    Does someone know why it's different.

    Thx
     
    Bibi69, Feb 1, 2007
    #1
    1. Advertising

  2. On Thu, 01 Feb 2007 11:52:48 +0100, Bibi69
    <> wrote:

    >Hi,
    >I've a question concerning variable types :
    >I want to add two 4 bits signed values and a one-bit value.
    >What seems to be the most efficient method to me is to use a 4-bit adder
    >with a carry-in bit.


    Synthesis tools should do this automatically for you.

    >If I write
    >i1 : in std_logic_vector(3 downto 0);
    >i2 : in std_logic_vector(3 downto 0);
    >ci : in std_logic;
    >o : out std_logic_vector(3 downto 0);
    >
    >o <= i1+i2+ci;
    >
    >the synthesis (with xilinx ise 8.1) is ok but people have said me it's
    >bad to add std_logic_vector and std_logic.


    I agree. Arithmetic on std_logic_vector is a really, really bad idea.

    >When I use signed and bit types, the synthesizer tells '+' isn't a
    >correct operator...


    >Does someone have a piece of advice on what I should do ?


    Use numeric_std or std_logic_arith, make all your operands SIGNED,
    and then be VERY careful; because a single-bit SIGNED vector has
    only two values, 0 and -1 !!!!!!!

    signal i1, i2: signed(3 downto 0);
    signal t1: signed(3 downto 0); -- sum
    signal c1: std_logic; -- carry in
    ....

    t1 <= i1 + i2 + signed' ('0' & c1);

    NOTE I've put a leading 0 on the carry, to ensure that its numeric
    value is either 0 or +1.

    >Moreover I want to have three such adders making a tree structure.
    >If I write :
    >i1 : in std_logic_vector(3 downto 0);
    >i2 : in std_logic_vector(3 downto 0);
    >i3 : in std_logic_vector(3 downto 0);
    >i4 : in std_logic_vector(3 downto 0);
    >c1 : in std_logic;
    >c2 : in std_logic;
    >c3 : in std_logic;
    >o : out std_logic_vector(3 downto 0);
    >
    >I tried o <= (i1+i2+c1)+(i3+i4+c2)+c3;
    >That doesn't give an efficient result, no adder tree.
    >To have a good tree structure I have to write :
    >signal t1 : std_logic_vector(3 downto 0);
    >signal t2 : std_logic_vector(3 downto 0);
    >
    >t1 <= i1+i2+c1;
    >t2 <= i3+i4+c2;
    >o <= t1+t2+c3;
    >
    >Does someone know why it's different.


    I don't; it's a feature of your tool's optimisations.
    I do know, though, that it's wrong; what happens to the
    carry OUT from the most significant bits?

    The result of i1+i2+c1 needs to be 5 bits, and the
    result of the tree sum needs to be 6 bits. For this
    to work, you need to resize one of the operands to
    that same bit width. Here's how I'd do it:

    signal t1,t2: signed(4 downto 0);
    signal sum: signed(5 downto 0);
    ....
    t1 <= i1 + i2 + (signed' ("0000") & c1);
    t2 <= i3 + i4 + (signed' ("0000") & c2);
    sum <= t1 + t2 + (signed' ("00000") & c3);

    --
    Jonathan Bromley, Consultant

    DOULOS - Developing Design Know-how
    VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

    Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK

    http://www.MYCOMPANY.com

    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.
     
    Jonathan Bromley, Feb 1, 2007
    #2
    1. Advertising

  3. Bibi69

    Andy Guest

    On Feb 1, 4:52 am, Bibi69 <> wrote:
    > Hi,
    > I've a question concerning variable types :
    > I want to add two 4 bits signed values and a one-bit value.
    > What seems to be the most efficient method to me is to use a 4-bit adder
    > with a carry-in bit.
    > If I write
    > i1 : in std_logic_vector(3 downto 0);
    > i2 : in std_logic_vector(3 downto 0);
    > ci : in std_logic;
    > o : out std_logic_vector(3 downto 0);
    >
    > o <= i1+i2+ci;
    >
    > the synthesis (with xilinx ise 8.1) is ok but people have said me it's
    > bad to add std_logic_vector and std_logic.
    >
    > When I use signed and bit types, the synthesizer tells '+' isn't a
    > correct operator...
    >
    > Does someone have a piece of advice on what I should do ?
    >
    > Moreover I want to have three such adders making a tree structure.
    > If I write :
    > i1 : in std_logic_vector(3 downto 0);
    > i2 : in std_logic_vector(3 downto 0);
    > i3 : in std_logic_vector(3 downto 0);
    > i4 : in std_logic_vector(3 downto 0);
    > c1 : in std_logic;
    > c2 : in std_logic;
    > c3 : in std_logic;
    > o : out std_logic_vector(3 downto 0);
    >
    > I tried o <= (i1+i2+c1)+(i3+i4+c2)+c3;
    > That doesn't give an efficient result, no adder tree.
    > To have a good tree structure I have to write :
    > signal t1 : std_logic_vector(3 downto 0);
    > signal t2 : std_logic_vector(3 downto 0);
    >
    > t1 <= i1+i2+c1;
    > t2 <= i3+i4+c2;
    > o <= t1+t2+c3;
    >
    > Does someone know why it's different.
    >
    > Thx


    You can use integer subtypes for arithmetic as well.

    subtype sum_type is integer range -8 to 7;
    variable i1, i2, sum : sum_type;
    variable ci : integer range 0 to 1;

    Have you thought about what you want to happen if the sum rolls over?
    Vector based arithmetic will silently roll over, which is usually fine
    for counters, but not always what you wanted for adders, especially
    signed ones. With vector based arithmetic, detecting signed rollovers
    is a little more complicated.

    With integer subtypes, all operations are assumed 32 bit signed, no
    matter what the storage variable range is. Then the synthesis tool
    figures out how many bits it really needs to keep. So you can do
    something like:

    if i1 + i2 + ci > sum_type'high then -- don't try this with vectors!
    sum := sum_type'high; -- assuming 'high is 2**n - 1
    elsif i1+ i2 + ci < sum_type'low then
    sum := sum_type'low; -- assuming 'low is -(2**n)
    else
    sum := i1 + i2 + ci;
    end if;

    Since the results of the addition are 32 bit signed, they can be
    checked against the limits of the sum variable type, before trying to
    store the results there. The synthesis tool automatically recognizes
    the three identical adders, and uses just one, with the extra bit (not
    stored) for the rollover detection.

    Or, if it is never supposed to roll over, don't do any checking, and
    if it does by chance, the simulator will tell you about it.

    And, integer arithmetic simulates much more quickly than vector based
    arithmetic.

    You can also use the new fixed point package, but the default size for
    sum result is one bit larger than the largest addend, and you'd need
    to resize & saturate if that's not what you want. And it simulates as
    slow as any other vectors.

    Andy
     
    Andy, Feb 1, 2007
    #3
    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. luna
    Replies:
    1
    Views:
    13,892
    Kevin Spencer
    Feb 6, 2004
  2. pozz
    Replies:
    8
    Views:
    345
    Jack Klein
    Jul 20, 2006
  3. Replies:
    5
    Views:
    984
    X-Centric
    Jun 30, 2005
  4. darrel
    Replies:
    4
    Views:
    869
    darrel
    Jul 19, 2007
  5. jobs

    int to numeric numeric(18,2) ?

    jobs, Jul 21, 2007, in forum: ASP .Net
    Replies:
    2
    Views:
    1,022
    =?ISO-8859-1?Q?G=F6ran_Andersson?=
    Jul 22, 2007
Loading...

Share This Page