2013-03-04 83 views
29

我以前一直使用该用于检测上升沿:clk'event VS rising_edge()

if (clk'event and clk='1') then

但是这也可以使用:

if rising_edge(clk) then

this postrising_edge(clk)推荐,但也有a comment表明rising_edge(clk)可能导致错误的行为。

我不能决定选择哪一个,以(clk'event and clk='1')或采用rising_edge(clk)继续。

在这两方面的任何现实世界的expereince?任何偏好?

谢谢!

+0

可以在子程序体内使用“if(rising_edge(clk))”吗? – 2016-07-04 10:12:18

+1

@VineetDeoraj当然可以。在某些情况下,它可能没有意义或可以合成(例如,如果子程序在由不同时钟触发的进程中调用),但这是另一个问题。 – 2016-08-15 11:25:33

回答

29

rising_edge定义为:

FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN IS 
BEGIN 
    RETURN (s'EVENT AND (To_X01(s) = '1') AND 
         (To_X01(s'LAST_VALUE) = '0')); 
END; 

FUNCTION To_X01 (s : std_ulogic) RETURN X01 IS 
BEGIN 
    RETURN (cvt_to_x01(s)); 
END; 

CONSTANT cvt_to_x01 : logic_x01_table := (
        'X', -- 'U' 
        'X', -- 'X' 
        '0', -- '0' 
        '1', -- '1' 
        'X', -- 'Z' 
        'X', -- 'W' 
        '0', -- 'L' 
        '1', -- 'H' 
        'X' -- '-' 
        ); 

如果时钟只从0变为1,并且从1到0,然后rising_edge会产生相同的代码。否则,你可以解释这种差异。

就我个人而言,我的时钟只能从0到1,反之亦然。我发现rising_edge(clk)(clk'event and clk = '1')变体更具描述性。

+6

在仿真启动时,如果时钟从“U”变为“1”,rising_edge(clk)将为false,但手写边缘检测“event and 1”将为true。在这个特定的情况下,rising_edge会更安全。 – wap26 2013-03-04 16:22:32

+0

那么'如果(clk'last_value ='0'和clk ='1')然后'完成相同的事情? – Nate 2015-04-05 17:59:56

+1

这是有争议的评论 - 它很好,因为它给出了rising_edge()机制的明确定义;对于'H'到1和'1'到L转换的rising_edge()的优点是矛盾的。我的选择 - 没有充分的理由使用'事件和1'构造 - 完全同意伊恩沃尔的答案。 – vleo 2015-05-08 15:17:27

13

链接的注释不正确:'L'到'1'会产生上升沿。此外,如果您的时钟信号从'H'转换为'1',rising_edge(clk)将(正确)不会触发,而(clk'event and clk = '1')(不正确)会。当然,这可能看起来像一个人为的例子,但由于其他地方的失败,我已经看到时钟波形在真实的硬件中执行。

8

实例:

试想,你在造型像一个I2C总线(称为信号数据SCL时钟和SDA),其中总线是三态和两网有弱上拉向上。您的测试平台应该将PCB上的上拉电阻值设为'H'。

scl <= 'H'; -- Testbench resistor pullup 

你的I2C主设备或从设备可以驱动总线为“1”或“0”或通过分配“Z”

分配一个“1”到SCL净将导致离开它单独一个事件发生,因为SCL的价值发生了变化。

  • 如果你有一行代码依赖于(scl'event and scl = '1'),那么你会得到一个错误的触发器。

  • 如果您有一行代码依赖于rising_edge(scl),那么 您将不会得到错误的触发。

继续举例:给SCL分配一个'0',然后分配一个'Z'。 SCL网络变为'0',然后回到'H'。在这里,从'1'到'0'不会触发任何一种情况,但是从'0'到'H'将触发rising_edge(scl)条件(正确),但(scl'event and scl = '1')的情况会错过它(错误的)。

一般Recommenation:

使用rising_edge(clk)falling_edge(clk)而不是clk'event所有代码。

+1

您的示例成功地演示了不使用设备引脚缓冲区的设计描述的谬误。在现实生活中,当复位未被置位时,您不会传播除'X','0'或'1'之外的任何触发器的时钟输入。这个问题不是由于采用特定的IEEE Std 1076.6-2004认可的边缘敏感时序逻辑表示方法造成的。问题在于特定的供应商是否会允许TO_X01(scl)正式或类似的。 – user1155120 2013-08-09 04:38:20

相关问题