信号vs变量



VHDL提供了两种主要的对象类型来保存数据,名称signalvariable,但我找不到任何地方清楚何时使用一种数据类型而不是另一种。有没有人能说明他们的优势/局限/范围/综合/使用其中一个会比另一个更好的情况?

信号可用于在进程之间传递值。变量不能。有shared variables可以在较旧的编译器,但你真的要求的问题(与竞争条件),如果你这样做-除非你使用protected types有点像类。然后它们用于通信是一样的,但(据我所知)不是可合成的。

这种对通信的基本限制来自于信号和变量的更新方式。

最大的区别在于变量被赋值后立即更新(使用:=操作符)。信号在赋值时(使用<=操作符)有一个更新计划,但是任何人在读取信号时看到的值直到一段时间过去才会改变。

(旁白:这段时间可以像delta周期一样小,这是VHDL模拟器中最小的时间——没有"真实"的时间流逝。像wait for 0 ps;这样的代码会使模拟器在继续之前等待下一个增量周期。

如果您需要相同的逻辑将提供给多个触发器,变量是将逻辑分解为单个点的好方法,而不是复制/粘贴代码。

在逻辑上,在一个时钟进程中,信号总是推断触发器。变量既可以用于组合逻辑和推断触发器。有时对于同一个变量,两者都有。有些人认为这很混乱,我个人认为还好:

process (clk)
  variable something : std_logic;
  if rising_edge(clk) then
    if reset = '1' then
       something := '0';
    else
       output_b <= something or input c; -- using the previous clock's value of 'something' infers a register
       something := input_a and input_b; -- comb. logic for a new value
       output_a <= something or input_c; -- which is used immediately, not registered here
    end if;
  end if;
end process;

使用变量需要注意的一点是,因为如果它们在写入后被读取,则不使用寄存器输出,您可以获得长链逻辑,这可能导致丢失fmax目标

使用信号(在时钟进程中)需要注意的一点是,它们总是推断寄存器,从而导致延迟。

正如其他人所说,信号在时间片结束时更新为新值,但变量立即更新。

// inside some process
// varA = sigA = 0. sigB = 2
varA := sigB + 1;      // varA is now 3
sigC <= varA + 1;      // sigC will be 4
sigA <= sigB + 1;      // sigA will be 3
sigD <= sigA + 1;      // sigD will be 1 (original sigA + 1)

对于硬件设计,我很少使用变量。通常情况下,当我在编写一些确实需要重构代码的功能时,但我是在截止日期前。我避免使用它们,因为我发现处理信号和变量的心理模型太不同了,无法在一段代码中很好地生活。这并不是说它不能做到,但我认为大多数RTL工程师避免混合……你不能避免信号。

其他点:

  • 信号具有实体作用域。变量是进程的局部变量。
  • 两个合成

最新更新