2011-11-03 43 views
2

VHDL提供了两种主要的对象类型来保存数据,NAMEL signalvariable,但我无法找到任何地方是在什么时候比其他使用一个数据类型明确。任何人都可以阐明他们的优势/局限性/范围/综合/使用哪一个比另一个好?信号VS可变

回答

5

信号可用于在进程之间传递值。变量不能。有shared variables可以在较老的编译器中使用,但如果你这样做的话,你确实需要问题(有竞争条件) - 除非你使用protected types,这有点像类。然后他们是相同的用于沟通,但没有(据我所知)合成。

通信的这个基本限制来自信号和变量更新的工作方式。

最大的区别是因为变量立即更新而被更新(与:=运算符一起)。信号有更新日期分配给(与<=运营商),但任何人看到他们读取信号的价值将不会改变,直到一段时间过去。 (除此之外:这个时间量可以和Δ循环一样小,这是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目标

使用信号(在时钟进程中)的一件事是它们总是推断一个寄存器,并因此导致延迟。

3

正如其他人所说的那样,信号在时间片的末尾用新值更新,但变量会立即更新。

// 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工程师避免混合......并且无法避免信号。

其他景点:

  • 信号具有实体的作用域。变量是本地流程。
  • 两种合成
+2

,如果你不使用变量这很好,但许多工程师使用他们所有的时间。一个公开的例子是用于航空航天应用的GRLIB/LEON3。 – Philippe

+0

够公平的,每个人都有自己的风格。我倾向于在合同中移动一点点,我只是根据我所做的观察来评论我的意见。使用它们本质上没有什么错误。 –