Multiple input Adder

A

Adrian Spilca

Guest
Is there a way to describe a N-input Adder?
I mean just behaviour, no use of lib components?

I couldn't think of any other way of describing the operation but
sum = sum + op(i)

In other words, here is what I have in mind but this obviously doesn't work
(don't be bothered by the sintax)

signal op is array (0 to N) of signed (..)

NinAdd: process (reset, op)
begin
if (reset = '0') then
sum <= (others => '0');
else
for i in 0 to N loop
sum <= sum + op(i);
end loop;
end if;
end process NinAdd;

I tried "for .. generate" which is more appropriate being a concurrent
statement but then I don't know how to initialise the sum (reset signal).

Regards,
Adrian
 
What I'm afraid of here is that describing the process with variables
instead of signals will make the compiler generate an accumulator instead
of a parallel N-input Adder.

[...]
for i in N downto 0 loop
temp_sum := temp_sum + op(i);
end loop;
[...]
You should
generally understand that this isn't really a loop, it's a
"description" of what you want your piece of hardware to do, and your
compiler/synthesis tool is smart enough to understand it and unfold the
loop to an N-input adder.
Are you sure about that?

I hope you are right, but at the moment I can only simulate my design, so I
can't be sure of the generated Adder. How can I describe the Accumulator
then? (rhetorical question)

Regards
Adrian
 
skatoulas@hotmail.com wrote:

If by an accumulator you mean an add and store device,
yes, this is what I meant

that would have
to be a clocked piece of hardware with only a single input, a register
and an adder, something like this:

[...]
begin
wait until clk'event and clk='1';
temp_sum := temp_sum + ip;
great
so, the clock is the big difference

[...]
HDL Synthesis Report

Macro Statistics
# Adders/Subtractors : 9
10-bit adder : 9

i.e. a chain of 9 10-bit adders (for a 10 input 10-bit case). This is a
bit inefficient though in the sense that you have the full
combinatorial delay of 10 adders in a row. Breaking it in pairs is
better but costs more adders. Hope this helps.
It surely does, thanks.
Altough I'm only half happy because of this cascade, but I suppose this is
the limitation of behavioural description. Further optimisation could be
done by defining proper carry select macro, isn't it.

Still, can we call this an N-input Adder? I guess we can, looking at it as a
block... It was not the original meaning though.

Anyway, it's all much clearer now. I'll try using variables instead of
signals and I guess this is all can do with behavioural.

Many thanks,
Adrian
 
preferably do it like this:

--your inputs
signal op is array (0 to N) of signed (...)
--your output
signal sumOfNnumbers : signed(...)

--your N input adder
NinAdd : process(op)
variable temp_sum : signed(...);
begin
temp_sum := 0;

for i in N downto 0 loop
temp_sum := temp_sum + op(i);
end loop;

--assign the temporary result to the output signal
sumOfNnumbers <= temp_sum;
end process NinAdd;

you don't really need the reset signal here, the whole result of the
addition gets re-computed when any of the inputs changes. You should
generally understand that this isn't really a loop, it's a
"description" of what you want your piece of hardware to do, and your
compiler/synthesis tool is smart enough to understand it and unfold the
loop to an N-input adder. I am probably wrong but I think to use the
generate statement you'd have to build something like a pyramid of
adders and add things in pairs. Hope this helps
 
If by an accumulator you mean an add and store device, that would have
to be a clocked piece of hardware with only a single input, a register
and an adder, something like this:

--your input
signal ip : signed(...);
--your output
signal sum : signed(...);

--the accumulator
Accum : process
variable temp_sum : signed(...);
begin
wait until clk'event and clk='1';
temp_sum := temp_sum + ip;

sum <= temp_sum;
end if;

This would then add the input to the previous sum on every new clock
cycle. If you wanted to take the new input from a different element of
the input array you could also increment a counter on every clock and
use its output to access the elements of the input array. Now given
that you define a combinatorial process, it has to be an N-input adder
as there is no other way. Just to check, I synthesized the following
N-input adder for you:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity ninadd is
Generic ( num_of_inputs : integer := 10;
size_of_each_input : integer := 10);

Port ( ip : in std_logic_vector(num_of_inputs * size_of_each_input
- 1 downto 0);
sum : out std_logic_vector(size_of_each_input - 1 downto
0));
end ninadd;

architecture Behavioral of ninadd is

begin


--your N input adder
NinAdd : process(ip)
variable temp_sum : unsigned(size_of_each_input - 1 downto 0);
begin
temp_sum := (others=>'0');
for i in num_of_inputs-1 downto 0 loop
temp_sum := unsigned(temp_sum) + unsigned(ip(i*size_of_each_input
+ size_of_each_input - 1downto
i*size_of_each_input));
end loop;


--assign the temporary result to the output signal
sum <= std_logic_vector(temp_sum);
end process NinAdd;

end Behavioral;

and what came out was

HDL Synthesis Report

Macro Statistics
# Adders/Subtractors : 9
10-bit adder : 9

i.e. a chain of 9 10-bit adders (for a 10 input 10-bit case). This is a
bit inefficient though in the sense that you have the full
combinatorial delay of 10 adders in a row. Breaking it in pairs is
better but costs more adders. Hope this helps.
 

Welcome to EDABoard.com

Sponsor

Back
Top