求和向量的动态数量

Sum dynamic amount of vectors

我基本上有两个向量(类型:整数、有符号、无符号,std_logic_vector,对于实现来说并不重要)。

向量 1 的静态大小为 16(等于 1 个字)。 向量 2 的动态大小为 X*16(等于 X 个字) X是动态参数。

现在我想要一个结构,我可以根据参数 X 对向量 2 中的 X 个词求和。

……像这样:

vector_1 <= for i in 0 to X generate
             vector_2(X*16+15 downto X*16) +
            end generate;

任何人都可以想象在 VHDL 中可以实现这样的事情吗?

干杯, 斯蒂芬

编辑:也许为了更清楚,我想要的是:

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 在合成时是静态的。

对于您的 data_vector,我会使用自定义类型,例如:

type WORD_ARRAY_type is array (integer range <>) of signed (15 downto 0);
signal data_vector : WORD_ARRAY_type (2 downto 0);

这样您的总和就更具可读性,例如:

vector1 <= data_vector (0) + data_vector (1) + data_vector (2);

单周期代码应该是这样的:

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;

尽管工具可以将其解释为单周期多输入总和,但它们可能不会。

但是,具有 8 个输入的加法器会非常慢。我的方法是这样的:

  • 计数器设置为在达到 X 后停止。
  • 由可变大小多路复用器馈送的累加器。
  • 连接到向量 1 和向量 2 的多路复用器输入,由计数器控制。
  • 根据计数控制累加器的状态机或类似设备(即一旦达到 X 就停止添加)。

也解决了:

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;

一个函数可以用来求和,其中X是通过简单的长度除法确定的:

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;

函数的用法如下:

vector_1 <= vector_sum(vector_2, vector_1'length);