总和动态量的向量

时间:2015-07-10 10:35:50

标签: vhdl

我基本上有两个向量(类型:整数,有符号,无符号,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在合成时是静态的。

3 个答案:

答案 0 :(得分:2)

对于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就停止。
  • 由可变大小的多路复用器馈送的累加器。
  • 多路复用器输入连接到Vector 1和Vector 2,由计数器控制。
  • 状态机或类似的控制累加器,基于计数(即达到X时停止添加)。

答案 1 :(得分:1)

可以使用函数来求和,其中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);

答案 2 :(得分:0)

也解决了这个问题:

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;