这个简单的VHDL for循环有什么问题?

时间:2015-03-20 21:50:18

标签: vhdl modelsim quartus

由于某种原因,OutputTmp变量在模拟中始终未初始化。我可以让它在没有for循环的情况下工作,但我真的想要自动化它,以便我可以稍后转向更大的向量。中间变量工作正常。

注意:我是一名DBA和C#程序员,对VHDL来说还是新手,对不起,如果这是一个愚蠢的问题。

architecture Arch of VectorMultiplier4 is

signal Intermediate : std_logic_vector(0 to 4);
signal OutputTmp : std_logic;

begin

process (Intermediate)
begin

  for i in 0 to 4 loop
    Intermediate(i) <= (VectorA(i) AND VectorB_Reduced(i));    
  end loop;

  --THIS IS WHAT DOES NOT WORK APPARENTLY
  OutputTmp <= '0';
  for i in 0 to 4 loop
    OutputTmp <= OutputTmp XOR Intermediate(i);
  end loop;
Output <= OutputTmp;
end process;

end architecture;

谢谢!

2 个答案:

答案 0 :(得分:2)

这与fru1tbat指向的答案略有不同。

信号分配的一个特征是它被安排用于当前或未来的模拟时间。当任何模拟过程未决时,任何信号分配都不会生效(并且所有涉及信号的语句都被转换为保留层次结构和进程或只是进程的块语句。)

在同一模拟周期中,您不能依赖刚刚分配的信号值(计划更新)。

新信号值在当前模拟周期中不可用。

在下一个模拟周期中,波形中没有延迟的信号分配(无after Time)将是可用的,这将是一个增量周期。你只能“看到”信号的当前值。

因为OutputTmp似乎被命名为中间值,所以您可以将其声明为过程中的变量(删除信号声明,或重命名其中一个)。

    process (VectorA, VectorB_Reduced)
        variable OutputTmpvar:  std_logic;
        variable Intermediate: std_logic_vector (0 to 4);
    begin

      for i in 0 to 4 loop
        Intermediate(i) := (VectorA(i) AND VectorB_Reduced(i));    
      end loop;

      -- A variable assignment takes effect immediately
      OutputTmpvar := '0';
      for i in 0 to 4 loop
        OutputTmpvar := OutputTmpv XOR Intermediate(i);
      end loop;
    Output := OutputTmpvar;
    end process;

这将产生Intermediate数组元素的奇数奇偶值。

请注意,由于同样的原因,Intermediate也已变为变量,而VectorAVectorB_Reduced已放入敏感度列表而不是Intermediate

所有这些都可以进一步减少。

    process (VectorA, VectorB_Reduced)
        variable OutputTmpvar:  std_logic;
    begin

      -- A variable assignment takes effect immediately
      OutputTmpvar := '0';
      for i in 0 to 4 loop
        OutputTmpvar := OutputTmpvar XOR (VectorA(i) AND VectorB_Reduced(i));
      end loop;
    Output <= OutputTmpvar;
    end process;

正在删除Intermediate

为合成和尺寸可扩展性量身定制

如果你需要合成循环:

    process (VectorA, VectorB_Reduced)
        variable OutputTmp: std_logic_vector (VectorA'RANGE) := (others => '0');
    begin

      for i in VectorA'RANGE loop
          if i = VectorA'LEFT then
              OutputTmp(i) := (VectorA(i) AND VectorB_Reduced(i));
          else 
              OutputTmp(i) := OutputTmp(i-1) XOR (VectorA(i) AND VectorB_Reduced(i));
          end if;
      end loop;
    Output <= OutputTmp(VectorA'RIGHT);
    end process;

假设VectorAVectorB_reduced具有相同的维度(边界)。

这样做是为了提供具有唯一名称的合成结果'网表'的节点,并将生成由五个AND门提供的四个XOR门链。

此过程还演示了如何使用属性处理任何大小匹配的边界输入数组(示例中为VectorAVectorB_Reduced)。如果你需要处理具有不同边界但是你可以创建相同长度的两个输入的情况 它们的变量副本具有相同的边界,如果在函数中实现,则您需要做的事情。

展平XOR链是使用性能约束在合成域中处理的事情。 (对于许多FPGA架构,由于XOR的可交换和关联属性,XOR将适合一个LUT。)

(上述过程已在VHDL模型中进行了分析,阐述和模拟)。

答案 1 :(得分:1)

当您进入VHDL流程时,信号会保持其值,直到流程完成(或等待到达)。因此,分配OutputTmp的所有行都可以替换为

OutputTmp <= OutputTmp XOR Intermediate(4);

如果您在进入流程时未知,那么显然可以使OutputTmp保持未知。

编程时,所有语句都是一个接一个地执行。在HDL中,所有语句都是同时执行的。您可以在VHDL中使用变量来实现与C中相同的组合,但我不建议那些愿意学习VHDL进行综合的初学者。