实现FOR-LOOP和FOR-GENERATE的实际区别是什么?什么时候使用一个比另一个好?

实现FOR-LOOP和FOR-GENERATE的实际区别是什么?什么时候使用一个比另一个好?,for-loop,vhdl,fpga,hardware-programming,asic,For Loop,Vhdl,Fpga,Hardware Programming,Asic,假设我必须在一个标准逻辑向量上测试不同的位。最好实现一个进程,即为每个位执行循环,还是使用for generate实例化“n”个进程,每个进程测试一个位 FOR-LOOP 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 t

假设我必须在一个标准逻辑向量上测试不同的位。最好实现一个进程,即为每个位执行循环,还是使用for generate实例化“n”个进程,每个进程测试一个位

FOR-LOOP

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和几个进程,我使用了更多的区域,但是这个工具能够更快地计算所有内容,我的计时结果也更好。那么,这是否意味着在规则中,使用额外面积和较低复杂性的生成总是更好,还是我必须验证每个实现可能性的情况之一?

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

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循环的
是顺序语句,包含顺序语句(即,每个迭代都按顺序在前一个迭代之后执行)。generate的
循环是并发语句,包含并发语句,例如,您可以使用它来创建组件的多个实例

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

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

在这个基础上,我(稍微)更喜欢
,因为。。。循环
版本,因为它将程序逻辑本地化,而“生成”版本将其全球化,将其置于
流程
样板文件之外。如果您发现
循环
版本稍微容易阅读,那么您会在某种程度上同意

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

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

不同版本的工具会消除(偶尔会引入)此类缺陷。您可能会发现ISE的“使用新解析器”选项(适用于Spartan-6之前的部件)或Vivado或Synplicity在ISE的旧解析器不具备的地方实现了这一点。(例如,将信号传递出过程,较旧的ISE版本有严重的错误)

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


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

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