求和向量的动态数量
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);
我基本上有两个向量(类型:整数、有符号、无符号,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);