Reputation: 159
I basically have two vectors (type: integer, signed, unsigned, std_logic_vector, doesn't really matter for the imlementation).
Vector 1 has a static size of 16 (equals 1word). Vector 2 has a dynamic size of X*16 (equals X words) X is the dynamic parameter.
Now I want to have a construct where I can sum X words from vector 2 depending on the parameter X.
sth. like this:
vector_1 <= for i in 0 to X generate
vector_2(X*16+15 downto X*16) +
end generate;
Anyone can imagine something like this being possible in VHDL?
Cheers, Steffen
EDIT: Maybe to make it more clear, what I want to have:
accumulated_data <= std_logic_vector( signed(data_vector(0*16+15 downto 0*16)) +
signed(data_vector(1*16+15 downto 1*16)) +
...
signed(data_vector(X*16+15 downto X*16))
);
X is static at synth.
Upvotes: 1
Views: 584
Reputation: 4374
For your data_vector
, I would use a custom type, something like:
type WORD_ARRAY_type is array (integer range <>) of signed (15 downto 0);
signal data_vector : WORD_ARRAY_type (2 downto 0);
Your sum is then more readable, something like:
vector1 <= data_vector (0) + data_vector (1) + data_vector (2);
The single-cycle code would be something like this:
process (clk)
variable sum : signed (vector1'range) := to_signed(0, vector1'length);
begin
if (rising_edge(clk)) then
sum := to_signed(0, vector1'length);
for i in 0 to (data_vector'length - 1) loop
sum := sum + data_vector(i);
end loop;
vector1 <= sum;
end if;
end process;
Although it is up to the tools to interpret this as a single cycle multi-input sum, which they may not.
However, an adder with 8 inputs is going to be very slow. My approach would be something like this:
X
.X
is reached).Upvotes: 3
Reputation: 15924
A function can be used to do the sum, where X is determined through simple length division:
function vector_sum(vec_2 : std_logic_vector; len_1 : natural) return std_logic_vector is
variable res : std_logic_vector(len_1 - 1 downto 0) := (others => '0');
begin
for i in 0 to vec_2'length / len_1 - 1 loop
res := std_logic_vector(signed(res) +
signed(vec_2((i + 1) * len_1 - 1 + vec_2'right downto
i * len_1 + vec_2'right)));
end loop;
return res;
end function;
The function is then used like:
vector_1 <= vector_sum(vector_2, vector_1'length);
Upvotes: 1
Reputation: 159
Solved it as well:
process(clk)
variable TMP : std_logic_vector(accumulated_data'range) := (others => '0');
begin
if(rising_edge(clk)) then
for i in 0 to X-1 loop
TMP := std_logic_vector( signed(TMP) +
signed(data_vector(i*25+24 downto i*25))
);
end loop;
accumulated_data <= TMP;
end if;
end process;
Upvotes: 0