/= 如何转换为 vhdl 中的实际硬件
How is /= translated to actual hardware in vhdl
我是 VHDL/FPGA 编程的初学者。我想比较两个 32 位 std_logic_vector
s。我目前正在使用:
if ( RX_FRAME(to_integer(s_data_counter)).Data /= REF_FRAME(to_integer(s_data_counter)).Data ) then
s_bad_frame <= '1';
state <= DONE;
end if;
这里RX_FRAME
和REF_FRAME
是std_logic_vector(31 downto 0)
的2个数组
我想知道综合工具如何将 /=
转换为硬件。
建议使用这个吗?或者我应该对相关向量执行 XOR
并检查结果向量是否为零?如果我执行 XOR
并检查零,它不会增加所需的硬件数量吗?
我正在使用 Vivado 设计套件 2015.3。
您应该与 /=
进行比较,才能真正受益于 VHDL 等语言和 Xilinx Vivado 等高级综合工具。
然后,综合工具将使用 FPGA 中的内部 LUT 来实现这一点,可能具有类似于用于可变参数的 XOR 门的功能,或者如果其中一个参数的计算结果为常量,则使用 AND/NOT 门。查看实际实现的最佳方式是在显示已实现设计的工具中调出 GUI 视图。
但是开始通过自己执行 XOR 门来双重猜测工具通常不是一个好主意,因为该工具通常可以更好地确定最佳实现。但是,如果您遇到该工具无法识别特定构造和 select 有效实现,那么使用更多接近编码风格的实现来指导该工具可能是个好主意,但对于 [=10 这样的比较=] 这种情况很少见。
正如 Morten 已经介绍的那样,比较操作在 LUT 中实现,执行某种 X(N)OR 和 AND/(N)OR 聚合。
但它可能会更快...
FPGA 具有快速进位链,可用于加速宽输入的比较操作,但综合工具大多不利用这种特殊资源。
如何使用进位链进行相等比较?
进位链可以实现为 kill-p传播链。这个命名来自波纹进位加法器,其中可以生成进位,从进位传播或被杀死。
比较器以主动进位开始(全部相等)。 LUT中的每一步计算:An = Bn。如果是,则传播进位位,否则将其杀死。
如果进位为高(初始值在链中存活)所有位都相等。
Morten Zilmer 的附录
我没有 equal 或 unequal 操作的示例代码,但我有一个类似的示例 prefix and
和 prefix or
运算符使用进位链来加速宽输入的计算。
prefix_and
计算:y(i) <= '1' when x(i downto 0) = (i downto 0 => '1') else '0';
解释:
得到的向量是 1
,直到找到第一个 0
,之后是 0
.
或者换句话说:从 0 to n
开始时在位置 i
找到的第一个零会杀死 所有剩余位,而不管输入位如何。
prefix_or
计算:y(i) <= '0' when x(i downto 0) = (i downto 0 => '0') else '1';
解释:
得到的向量是 0
,直到找到第一个 1
,之后是 1
.
或者换句话说:从 0 to n
开始时在位置 i
找到的第一个生成 一个并将其传播到所有剩余位,而不管输入位如何。
以下代码是 prefix_and
的通用 VHDL 描述。它独立于供应商,但在 Xilinx FPGA 上使用特殊原语 (MUXCY)。
architecture rtl of arith_prefix_and is
begin
y(0) <= x(0);
gen1: if N > 1 generate
signal p : unsigned(N-1 downto 1);
begin
p(1) <= x(0) and x(1);
gen2: if N > 2 generate
p(N-1 downto 2) <= unsigned(x(N-1 downto 2));
-- Generic Carry Chain through Addition
genGeneric: if VENDOR /= VENDOR_XILINX generate
signal s : std_logic_vector(N downto 1);
begin
s <= std_logic_vector(('0' & p) + 1);
y(N-1 downto 2) <= s(N downto 3) xor ('0' & x(N-1 downto 3));
end generate genGeneric;
-- Direct Carry Chain by MUXCY Instantiation
genXilinx: if VENDOR = VENDOR_XILINX generate
component MUXCY
port (
S : in std_logic;
DI : in std_logic;
CI : in std_logic;
O : out std_logic
);
end component;
signal c : std_logic_vector(N-1 downto 0);
begin
c(0) <= '1';
genChain: for i in 1 to N-1 generate
mux : MUXCY
port map (
S => p(i),
DI => '0',
CI => c(i-1),
O => c(i)
);
end generate genChain;
y(N-1 downto 2) <= c(N-1 downto 2);
end generate genXilinx;
end generate gen2;
y(1) <= p(1);
end generate gen1;
end architecture;
我是 VHDL/FPGA 编程的初学者。我想比较两个 32 位 std_logic_vector
s。我目前正在使用:
if ( RX_FRAME(to_integer(s_data_counter)).Data /= REF_FRAME(to_integer(s_data_counter)).Data ) then
s_bad_frame <= '1';
state <= DONE;
end if;
这里RX_FRAME
和REF_FRAME
是std_logic_vector(31 downto 0)
我想知道综合工具如何将 /=
转换为硬件。
建议使用这个吗?或者我应该对相关向量执行 XOR
并检查结果向量是否为零?如果我执行 XOR
并检查零,它不会增加所需的硬件数量吗?
我正在使用 Vivado 设计套件 2015.3。
您应该与 /=
进行比较,才能真正受益于 VHDL 等语言和 Xilinx Vivado 等高级综合工具。
然后,综合工具将使用 FPGA 中的内部 LUT 来实现这一点,可能具有类似于用于可变参数的 XOR 门的功能,或者如果其中一个参数的计算结果为常量,则使用 AND/NOT 门。查看实际实现的最佳方式是在显示已实现设计的工具中调出 GUI 视图。
但是开始通过自己执行 XOR 门来双重猜测工具通常不是一个好主意,因为该工具通常可以更好地确定最佳实现。但是,如果您遇到该工具无法识别特定构造和 select 有效实现,那么使用更多接近编码风格的实现来指导该工具可能是个好主意,但对于 [=10 这样的比较=] 这种情况很少见。
正如 Morten 已经介绍的那样,比较操作在 LUT 中实现,执行某种 X(N)OR 和 AND/(N)OR 聚合。
但它可能会更快...
FPGA 具有快速进位链,可用于加速宽输入的比较操作,但综合工具大多不利用这种特殊资源。
如何使用进位链进行相等比较?
进位链可以实现为 kill-p传播链。这个命名来自波纹进位加法器,其中可以生成进位,从进位传播或被杀死。
比较器以主动进位开始(全部相等)。 LUT中的每一步计算:An = Bn。如果是,则传播进位位,否则将其杀死。
如果进位为高(初始值在链中存活)所有位都相等。
Morten Zilmer 的附录
我没有 equal 或 unequal 操作的示例代码,但我有一个类似的示例 prefix and
和 prefix or
运算符使用进位链来加速宽输入的计算。
prefix_and
计算:y(i) <= '1' when x(i downto 0) = (i downto 0 => '1') else '0';
解释:
得到的向量是1
,直到找到第一个0
,之后是0
.
或者换句话说:从0 to n
开始时在位置i
找到的第一个零会杀死 所有剩余位,而不管输入位如何。prefix_or
计算:y(i) <= '0' when x(i downto 0) = (i downto 0 => '0') else '1';
解释:
得到的向量是0
,直到找到第一个1
,之后是1
.
或者换句话说:从0 to n
开始时在位置i
找到的第一个生成 一个并将其传播到所有剩余位,而不管输入位如何。
以下代码是 prefix_and
的通用 VHDL 描述。它独立于供应商,但在 Xilinx FPGA 上使用特殊原语 (MUXCY)。
architecture rtl of arith_prefix_and is
begin
y(0) <= x(0);
gen1: if N > 1 generate
signal p : unsigned(N-1 downto 1);
begin
p(1) <= x(0) and x(1);
gen2: if N > 2 generate
p(N-1 downto 2) <= unsigned(x(N-1 downto 2));
-- Generic Carry Chain through Addition
genGeneric: if VENDOR /= VENDOR_XILINX generate
signal s : std_logic_vector(N downto 1);
begin
s <= std_logic_vector(('0' & p) + 1);
y(N-1 downto 2) <= s(N downto 3) xor ('0' & x(N-1 downto 3));
end generate genGeneric;
-- Direct Carry Chain by MUXCY Instantiation
genXilinx: if VENDOR = VENDOR_XILINX generate
component MUXCY
port (
S : in std_logic;
DI : in std_logic;
CI : in std_logic;
O : out std_logic
);
end component;
signal c : std_logic_vector(N-1 downto 0);
begin
c(0) <= '1';
genChain: for i in 1 to N-1 generate
mux : MUXCY
port map (
S => p(i),
DI => '0',
CI => c(i-1),
O => c(i)
);
end generate genChain;
y(N-1 downto 2) <= c(N-1 downto 2);
end generate genXilinx;
end generate gen2;
y(1) <= p(1);
end generate gen1;
end architecture;