2 个 VHDL 数字在 1 个时钟周期内相加的宽度是否有任何限制?
Is There Any Limit to How Wide 2 VHDL Numbers Can Be To Add Them In 1 Clock Cycle?
我正在考虑在 VHDL 中添加两个 1024 位数字。
理想情况下,我想达到 100 MHz 的时钟频率。
目标是 Xilinx 7 系列。
2个数相加时,难免有进位。由于在计算出右侧的位之前无法计算左侧的进位位,因此对我来说似乎应该限制寄存器的宽度并且仍然可以在 1 个时钟周期内添加。
这是我的问题:
1.)FPGA是这样加数的吗?或者他们是否有某种不受进位问题影响的执行加法的方法?
2.) 宽度有限制吗?如果是这样,1024 是否在 100 MHz 时钟的合理范围内,还是自找麻烦?
也许这个可行,没试过:
library ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Calculator is
generic(
num_length : integer := 1024
);
port(
EN: in std_logic;
clk: in std_logic;
number1 : in std_logic_vector((num_length) - 1 downto 0);
number2 : in std_logic_vector((num_length) - 1 downto 0);
CTRL : in std_logic_vector(2 downto 0);
result : out std_logic_vector(((num_length * 2) - 1) downto 0));
end Calculator;
architecture Beh of Calculator is
signal temp : unsigned(((num_length * 2) - 1) downto 0) := (others => '0');
begin
result <= std_logic_vector(temp);
process(EN, clk)
begin
if EN ='0' then
temp <= (others => '0');
elsif (rising_edge(clk))then
case ctrl is
when "00" => temp <= unsigned(number1) + unsigned(number2);
when "01" => temp <= unsigned(number1) - unsigned(number2);
when "10" => temp <= unsigned(number1) * unsigned(number2);
when "11" => temp <= unsigned(number1) / unsigned(number2);
end case;
end if;
end process;
end Beh;
没有。你只需要选择一个合适的长时钟周期即可。
实际上,虽然没有基本限制,但对于任何给定的周期时间,都会有一些限制,具体取决于 FPGA 技术。
在 1024 位,我会考虑打破加法并对其进行流水线化。
作为单个周期实现,我希望 1024 位加法的速度大约为 5,也许是 10 MHz。 (这很容易检查:合成一个并查看时序报告!)
流水线并不是克服该限制的唯一方法。
还有“快速加法器”架构,如进位先行、进位保存(通过常用资源获取详细信息)......当 FPGA 将快速进位链构建到 LUT 结构中时,这些架构几乎已经过时了,但它们可能有像你这样的利基用途。然而,它们可能无法得到合成的最佳支持,因为(对于大多数目的)快速进位链就足够了。
我正在考虑在 VHDL 中添加两个 1024 位数字。
理想情况下,我想达到 100 MHz 的时钟频率。
目标是 Xilinx 7 系列。
2个数相加时,难免有进位。由于在计算出右侧的位之前无法计算左侧的进位位,因此对我来说似乎应该限制寄存器的宽度并且仍然可以在 1 个时钟周期内添加。
这是我的问题:
1.)FPGA是这样加数的吗?或者他们是否有某种不受进位问题影响的执行加法的方法?
2.) 宽度有限制吗?如果是这样,1024 是否在 100 MHz 时钟的合理范围内,还是自找麻烦?
也许这个可行,没试过:
library ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Calculator is
generic(
num_length : integer := 1024
);
port(
EN: in std_logic;
clk: in std_logic;
number1 : in std_logic_vector((num_length) - 1 downto 0);
number2 : in std_logic_vector((num_length) - 1 downto 0);
CTRL : in std_logic_vector(2 downto 0);
result : out std_logic_vector(((num_length * 2) - 1) downto 0));
end Calculator;
architecture Beh of Calculator is
signal temp : unsigned(((num_length * 2) - 1) downto 0) := (others => '0');
begin
result <= std_logic_vector(temp);
process(EN, clk)
begin
if EN ='0' then
temp <= (others => '0');
elsif (rising_edge(clk))then
case ctrl is
when "00" => temp <= unsigned(number1) + unsigned(number2);
when "01" => temp <= unsigned(number1) - unsigned(number2);
when "10" => temp <= unsigned(number1) * unsigned(number2);
when "11" => temp <= unsigned(number1) / unsigned(number2);
end case;
end if;
end process;
end Beh;
没有。你只需要选择一个合适的长时钟周期即可。
实际上,虽然没有基本限制,但对于任何给定的周期时间,都会有一些限制,具体取决于 FPGA 技术。
在 1024 位,我会考虑打破加法并对其进行流水线化。
作为单个周期实现,我希望 1024 位加法的速度大约为 5,也许是 10 MHz。 (这很容易检查:合成一个并查看时序报告!)
流水线并不是克服该限制的唯一方法。
还有“快速加法器”架构,如进位先行、进位保存(通过常用资源获取详细信息)......当 FPGA 将快速进位链构建到 LUT 结构中时,这些架构几乎已经过时了,但它们可能有像你这样的利基用途。然而,它们可能无法得到合成的最佳支持,因为(对于大多数目的)快速进位链就足够了。