0

由于某种原因,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;

谢谢!

4

2 回答 2

3

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

信号分配的一个特点是它被安排在当前或未来的模拟时间。当任何模拟过程未决时,实际上没有信号分配生效(并且所有涉及信号的语句都被分解为保留层次结构和进程的块语句或只是进程)。

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

新信号值在当前仿真周期中不可用。

没有波形延迟的信号分配 (no 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出于同样的原因,它也被设为变量,VectorA并且VectorB_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;

有一个假设VectorA并且VectorB_reduced具有相同的维度(边界)。

这样做的目的是为综合结果“网表”的每个节点提供一个唯一名称,并将生成由五个 AND 门馈送的四个 XOR 门链。

这个过程还展示了如何通过使用属性来处理任何大小匹配的边界输入数组(在示例中)VectorAVectorB_Reduced如果您需要处理两个输入具有不同边界但长度相同的情况,您可以创建具有相同边界的它们的可变副本,如果这是在函数中实现的,您希望在形式上这样做。

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

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

于 2015-03-20T22:37:21.197 回答
1

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

OutputTmp <= OutputTmp XOR Intermediate(4);

如果您在进入该过程时未知,则清楚地保持 OutputTmp 未知。

编程时,所有语句一个接一个地执行。在 HDL 中,所有语句同时执行。您可以在 VHDL 中使用变量来实现与 C 中相同的功能,但对于愿意学习 VHDL 进行综合的初学者,我不推荐它。

于 2015-03-20T22:19:36.610 回答