【问题标题】:What is the practical difference between implementing FOR-LOOP and FOR-GENERATE? When is it better to use one over the other?实现 FOR-LOOP 和 FOR-GENERATE 之间的实际区别是什么?什么时候使用一个比另一个更好?
【发布时间】:2015-10-02 07:47:18
【问题描述】:

假设我必须在 std_logic_vector 上测试不同的位。实现一个单独的进程,为每个位循环或使用 for-generate 实例化“n”个进程,每个进程测试一位会更好吗?

FOR循环

my_process: process(clk, reset) begin
  if rising_edge (clk) then
    if reset = '1' then
      --init stuff
    else
      for_loop: for i in 0 to n loop
        test_array_bit(i);
      end loop;
    end if;      
  end if; 
end process;

生成

for_generate: for i in 0 to n generate begin
my_process: process(clk, reset) begin
  if rising_edge (clk) then
    if reset = '1' then
      --init stuff
    else
      test_array_bit(i);
    end if;
  end if; 
end process;
end generate;

在这种情况下,对 FPGA 和 ASIC 实施有何影响? CAD工具容易处理什么?

编辑: 只需添加我给一位帮助者的回复,以使我的问题更清楚:

例如,当我在 ISE 上使用 for 循环运行一段代码时,综合摘要给了我一个公平的结果,需要很长时间来计算所有内容。当我重新编码我的设计时,这次使用 for-generate 和几个进程,我使用了更多的区域,但是该工具能够更快地计算所有内容,并且我的计时结果也更好。那么,它是否暗示了一条规则,即使用 for-generates 总是更好,但需要额外的面积和较低的复杂性,还是我必须验证每一种实现可能性的情况之一?

【问题讨论】:

    标签: for-loop vhdl fpga hardware-programming asic


    【解决方案1】:

    第一个 sn-p 等同于以下内容:

    my_process: process(clk, reset) begin
      if rising_edge (clk) then
        if reset = '1' then
          --init stuff
        else
          test_array_bit(0);
          test_array_bit(1);
          ............
          test_array_bit(n);
        end if;      
      end if; 
    end process;
    

    而第二个将为每个i 生成n+1 进程,以及重置逻辑和所有内容(这可能是一个问题,因为该逻辑将尝试从不同的过程)。
    一般来说,for 循环是顺序语句,包含顺序语句(即每次迭代都按顺序在前一个迭代之后执行)。 for-generate 循环是并发语句,包含并发语句,例如,您可以使用它来创建组件的多个实例。

    【讨论】:

    • 嗨,尤金,非常感谢您的回复。我很抱歉,但我应该更清楚我的问题。我知道编码的基础知识以及使用这两种结构的“逻辑”含义。我怀疑使用它们的实际结果。我将这个示例与一个简单的矢量一起用作展示案例,但实际上事情要复杂得多。所以,重新制定:如果我有一段代码应该在一个时钟周期内给我一个回复(或者并行运行它的所有内容,如果这更适合的话),从物理 lvl 的角度来看,什么是最好的实现战略?
    • 例如,当我在 ISE 上使用 for 循环运行一段代码时,综合摘要给了我一个公平的结果,需要很长时间来计算所有内容。当我重新编码我的设计时,这次使用 for-generate 和几个进程,我使用了更多的区域,但是这些工具能够更快地计算所有内容,并且我的时序结果也更好。那么,它是否暗示了一条规则,即使用 for-generates 总是更好,但需要额外的面积,还是我必须验证每一种实现可能性的情况之一?
    • 第二个实现的并行特性导致更快的计算。而且,与往常一样,需要权衡使用的资源数量。如果您查看两种实现的 RTL 示意图,您会发现差异。就个人而言,我在编码 RTL 逻辑时使用generate 循环,即在指定确切的硬件结构时,以及带有行为描述的for 循环(嗯,几乎从不:))
    • @Eugene Sh :for ... loop 版本本质上也是并行的,因为它必须在单个循环中执行。这些描述(忽略看不见的代码)完全相同。为什么综合不这样看待它们? ...好问题
    【解决方案2】:

    假设复位和测试功能中的逻辑相对简单(例如,相邻位之间没有交互),我会期望两者生成相同的逻辑。

    了解由于整个 for 循环在单个时钟周期内执行,因此综合将展开它并为每个输入位生成一个单独的 test_array_bit 实例。因此,综合工具很有可能为两个版本生成相同的逻辑 - 至少在这个简单的示例中是这样。

    在此基础上,我会(略微)更喜欢for ... loop 版本,因为它本地化程序逻辑,而“生成”版本将其全球化,将其置于process 样板之外。如果您发现loop 版本更易于阅读,那么您会在某种程度上同意。

    然而,教条式的风格是不值得的,你的实验说明了这一点:loop 合成劣质硬件。综合工具是复杂且不完美的软件,例如高度优化的编译器,并且有许多相同的问题。有时他们会错过“明显”的优化,有时他们会进行复杂的优化(例如在软件中),因为它增加的大小会破坏缓存。

    因此,最好尽可能以最简洁的风格编写,但在解决工具限制和偶尔出现的实际工具缺陷方面具有一定的灵活性。

    不同版本的工具会消除(偶尔会引入)此类缺陷。您可能会发现 ISE 的“使用新解析器”选项(适用于 Spartan-6 之前的部件)或 Vivado 或 Synplicity 可以在 ISE 的旧解析器无法做到的情况下做到这一点。 (例如,将信号传递出程序,旧 ISE 版本存在严重错误)。

    修改示例并查看综合是否可以在最简单的情况下“正确”(产生相同的硬件)并重新引入复杂性直到您发现哪个构造失败,这可能是有益的。

    如果您通过这种方式发现了一些具体的东西,那么值得在这里报告(通过回答您自己的问题)。 Xilinx 过去鼓励通过其 Webcase 系统报告此类缺陷;最终他们甚至被修复了!然而,他们似乎在过去一两年中停止了这种情况。

    【讨论】:

      猜你喜欢
      • 2020-06-08
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 2021-06-12
      • 1970-01-01
      • 2010-10-28
      • 2010-10-22
      • 1970-01-01
      相关资源
      最近更新 更多