Spyro
Spyro

Reputation: 159

Sum dynamic amount of vectors

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

Answers (3)

scary_jeff
scary_jeff

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:

  • A counter set to stop once it reaches X.
  • An accumulator fed by a variable size multiplexer.
  • Multiplexer inputs connected to Vector 1 and Vector 2, controlled by the counter.
  • State machine or similar to control the accumulator, based on the count (i.e. stop adding once X is reached).

Upvotes: 3

Morten Zilmer
Morten Zilmer

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

Spyro
Spyro

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

Related Questions