![]() |
|
|
|
#1 |
|
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 |
|
|
|
|
#2 |
|
Posts: n/a
|
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 |
|
|
|
#3 |
|
Posts: n/a
|
On Feb 1, 4:52 am, Bibi69 <nore...@free.fr> 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 |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Error: expected constructor, destructor or type conversion before '(' token | suse | Software | 0 | 03-09-2009 03:25 AM |
| Eclipse - Axis2 - Java Webservices Error | amanjsingh | Software | 1 | 10-09-2007 09:03 AM |
| Need help on Modelsim VHDL syntax? ASAP:) | kaji | General Help Related Topics | 0 | 03-14-2007 10:43 PM |
| Need help on a Modelsim VHDL Syntax? ASAP:) | kaji | Software | 0 | 03-14-2007 10:43 PM |
| Need Help on a Modelsim VHDL Syntax....ASAP:) | kaji | Hardware | 0 | 03-14-2007 10:41 PM |