2

我是 VHDL/FPGA 编程的初学者。我想比较两个 32-bit std_logic_vector。我目前正在使用:

      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;

这里是 2RX_FRAMEREF_FRAME数组std_logic_vector(31 downto 0)

我想知道综合工具是如何转化/=为硬件的。建议使用这个吗?或者我应该做一个XOR相关的向量并检查结果向量是否为零?如果我做一个XOR并检查零,它不会增加所需的硬件数量吗?我正在使用 Vivado 设计套件 2015.3。

4

2 回答 2

7

您应该进行比较/=才能真正受益于 VHDL 等语言和 Xilinx Vivado 等高级综合工具。

然后,综合工具将使用 FPGA 中的内部 LUT 来实现这一点,可能使用类似于变量参数的 XOR 门的功能,或者如果参数之一评估为常数,则使用 AND/NOT 门。查看实际实现的最佳方式是在工具中调出一个 GUI 视图来显示已实现的设计。

但是通过自己执行 XOR 门来开始双重猜测该工具通常是一个坏主意,因为该工具通常更好地确定最佳实现。但是,如果您遇到该工具无法识别特定结构并无法选择有效实现的情况,那么以接近编码风格的更多实现来引导该工具可能是一个好主意,但对于这样的比较来说,/=这种情况很少见。

于 2016-01-20T09:05:47.727 回答
2

正如 Morten 已经介绍的那样,比较操作在 LUT 中实现,执行某种 X(N)OR 和 AND/(N)OR 聚合。

但它可能会更快......
FPGA 具有快速进位链,可用于加速宽输入的比较操作,但综合工具大多不利用这种特殊资源。

如何使用进位链进行相等比较?
进位链可以实现为杀伤传播。此命名来自波纹进位加法器,其中可以生成进位,从进位传播或被杀死。

比较器以主动进位开始(全部相等)。每个步骤都在 LUT 中计算:An = Bn。如果是,则传播进位位,否则将其杀死。

如果进位很高(初始值在链中存活),所有位都相等。

Morten Zilmer 附录

我没有相等不相等运算的示例代码,但我有一个类似的示例,用于使用进位链来加速宽输入计算的运算符prefix andprefix or

  • prefix_and计算:y(i) <= '1' when x(i downto 0) = (i downto 0 => '1') else '0'; 解释:
    结果向量是1直到0找到第一个,之后它是0
    或者换句话说:无论输入位如何,在i从位置找到的第一个零都会0 to n 杀死所有剩余的位。

  • prefix_or计算:y(i) <= '0' when x(i downto 0) = (i downto 0 => '0') else '1';

    解释:
    得到的向量是0直到1找到第一个,之后它是1
    或者换句话说:在i从位置找到的第一个0 to n 生成一个,并将其传播到所有剩余的位,而不管输入位如何。

以下代码是prefix_and. 它独立于供应商,但在 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;

资源:PoC.arith.prefix_and

于 2016-01-20T23:23:55.537 回答