【问题标题】:How is /= translated to actual hardware in vhdl/= 如何在 vhdl 中转换为实际硬件
【发布时间】:2016-04-26 00:34:57
【问题描述】:

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

      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_FRAMEREF_FRAMEstd_logic_vector(31 downto 0)的2个数组

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

【问题讨论】:

    标签: comparison vhdl synthesis vivado hardware-programming


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

      Morten Zilmer 附录

      我没有 equalunequal 操作的示例代码,但我有一个使用进位链的 prefix andprefix or 运算符的类似示例加速宽输入的计算。

      • prefix_and 计算:y(i) &lt;= '1' when x(i downto 0) = (i downto 0 =&gt; '1') else '0'; 说明:
        结果向量为1,直到找到第一个0,之后为0
        或者换句话说:从0 to n 出发时在i 位置找到的第一个零杀死所有剩余的位,无论输入位如何。

      • prefix_or 计算:y(i) &lt;= '0' when x(i downto 0) = (i downto 0 =&gt; '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;
      

      来源:PoC.arith.prefix_and

      【讨论】:

      • 您能否添加一个简短的 VHDL 代码示例,它可能使综合工具映射到这样的技能传播链;是否需要使用特定于技术的模块?
      • @MortenZilmer 添加了一个示例。如果您还有其他问题,请contact我 :)。
      • 感谢您的示例,我看到前缀检查(最长的 0/1)可以从进位链中受益。但是对于一个链来说,时间是线性的(O(n) = n),一个简单的比较可以是一个树形结构,时间是对数的(O(n) = ln(n))。所以我不认为技能传播链可以更快地替代简单比较。
      • @VinayMadapura 是的,如果是相等(xnor)运算符,您可以在 VHDL 中预先计算 x(i) &lt;= a(i) xnor b(i);x &lt;= a xnor b;。然后你已经比较了每一位,但你不知道完整的x 向量是否被填充了。因此,您使用 prefix_and 来检查所有位。如果 prifix_and y 向量的进位 (MSB) 为 1,则向量中不存在零。当 prefix_and 映射到进位链时,xnor 操作映射到 LUT。此外,由于不需要中间进位值,因此综合可以将 3 个连续的 a 和 b 位映射到 Xilinx FPGA 的一个 LUT6。
      • @VinayMadapura 所以综合应该计算y(i/3) &lt;= (a(i+0) xnor b(i+ 0)) and (a(i+1) xnor b(i+1)) and (a(i+2) xnor b(i+2));,这会将进位链缩短3。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-08
      • 1970-01-01
      • 2022-08-16
      • 2022-01-14
      • 2016-08-27
      • 2011-08-20
      相关资源
      最近更新 更多