实现FOR-LOOP和FOR-GENERATE之间的实际区别是什么?何时最好使用其中之一?

9

假设我需要测试std_logic_vector上的不同位。是实现一个单一进程,对每个位进行for循环,还是使用for-generate实例化'n'个进程,每个进程测试一个位,哪种方式更好?

FOR-LOOP

使用for循环实现单一进程会更好一些。这样可以避免创建过多的进程,从而减少资源消耗。同时,通过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_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-generate,付出额外的区域和较低的复杂性的代价,还是我必须验证每个单独的实现可能性?
2个回答

6
假定复位和测试函数的逻辑相对简单(例如,相邻位之间没有交互作用),我希望两者都能生成相同的逻辑。
请注意,由于整个for循环在单个时钟周期内执行,综合器将展开它,并为每个输入位生成一个独立的test_array_bit实例。因此,在这个简单的示例中,综合工具很可能会为两个版本生成相同的逻辑。
基于此,我(略微)更喜欢for ... loop版本,因为它使程序逻辑局部化,而“generate”版本则使其全球化,将其放在process样板外面。如果您发现loop版本稍微容易阅读,则您会在某种程度上表示同意。
然而,风格上不能教条主义,您的实验说明了这一点:loop合成为低质量硬件。综合工具是复杂而不完美的软件,就像高度优化的编译器一样,并且共享许多相同的问题。有时它们会错过一个“显而易见”的优化,有时它们会进行复杂的优化,但(例如在软件中)由于其增加的大小破坏了缓存而运行得更慢。
因此,最好采用最清洁的风格编写代码,但需要一定的灵活性以解决工具限制和偶尔的实际工具缺陷。
不同版本的工具会消除(有时会引入)此类缺陷。您可能会发现ISE的“使用新解析器”选项(用于Spartan-6之前的部件)或Vivado或Synplicity可以在ISE的旧解析器无法完成的情况下正确处理此问题。 (例如,从过程中传递信号,旧版ISE存在严重错误)。
修改示例并查看是否可以对最简单的情况进行合成(生成相同的硬件),然后重新引入复杂性,直到找到哪个结构失败,这可能是有益的。
如果您以这种方式发现了具体的内容,请在此处报告(通过回答您自己的问题)。赛灵思曾经鼓励通过其Webcase系统报告此类缺陷;最终,它们甚至被修复了!但是在过去一两年中,它们似乎已经停止了这样做。

0

第一个代码片段等同于以下内容:

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循环是并发语句,包含并发语句,您可以使用它来创建组件的多个实例,例如。


嗨 Eugene,非常感谢你的回复。很抱歉,我应该在我的问题上更清楚些。我知道编码的基础知识和使用这两种结构的“逻辑”影响。我的疑问在于使用它们的实际结果。我只是用一个简单的向量作为示例,但实际情况要复杂得多。所以,重新表述一下:如果我有一段代码,应该在一个时钟周期内给我一个答案(或者如果这样更合适,同时运行所有内容),从物理层面来看,什么是最好的实现策略? - Felipe GM
例如,当我在ISE上使用for循环运行一段代码时,综合摘要给了我一个公正的结果,需要很长时间来计算所有内容。当我重新编写我的设计时,这次使用for-generate和几个进程,我使用了更多的面积,但工具能够更快地计算所有内容,我的时序结果也更好。那么,这是否意味着有一个规则,总是最好使用for-generates并付出额外的代价,还是其中一个我必须验证每个单独的实现可能性的情况? - Felipe GM
第二种实现的计算速度更快,这是由于其并行性质所致。而且,像往常一样,资源使用的数量存在权衡。如果你查看两种实现的RTL原理图,你会看到它们之间的差异。个人而言,在编写RTL逻辑时,我会使用generate循环来指定确切的硬件结构,并使用for循环进行行为描述(几乎从不使用)。 - Eugene Sh.
1
@Eugene Sh:for...loop版本也是固有的并行,因为它必须在单个周期内执行。这些描述(忽略看不见的代码)完全等效。为什么综合工具没有看到它们的方式?......好问题。 - user1818839

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接