web-dev-qa-db-ja.com

clk'event vs rising_Edge()

私はこれを常に立ち上がりエッジの検出に使用していました。

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

ただし、これも使用できます。

if rising_Edge(clk) then

この投稿rising_Edge(clk)を読むことをお勧めしますが、 コメント もあり、rising_Edge(clk)が間違った動作につながる可能性があることを示しています。

(clk'event and clk='1')を使用するか、rising_Edge(clk)を採用するか、将来的にどちらを選択するかを決定できません。

これら2つの現実世界の経験はありますか?好みは?

ありがとう!

36
Diego Herranz

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')_バリアントよりも記述的であることがわかりました。

35
Bill Lynch

リンクされたコメントは正しくありません。「L」から「1」にすると、立ち上がりエッジが生成されます。

さらに、クロック信号が「H」から「1」に遷移する場合、rising_Edge(clk)は(正しく)トリガーされませんが、(clk'event and clk = '1')(誤って)します。

確かに、これは不自然な例のように見えるかもしれませんが、他の場所での障害のために、実際のハードウェアでクロック波形がそれを行うのを見てきました。

14
Brian Drummond

実際の例:

I2Cバス(クロック用のSCLおよびデータ用のSDAと呼ばれる信号)のようなものをモデリングしていると想像してください。バスはトライステートで、両方のネットに弱いプルアップがあります。テストベンチは、PCBの値が 'H'のプルアップ抵抗をモデル化する必要があります。

_scl <= 'H'; -- Testbench resistor pullup
_

I2Cマスターまたはスレーブデバイスは、バスを「1」または「0」に駆動するか、「Z」を割り当ててそのままにしておくことができます。

SCLネットに「1」を割​​り当てると、SCLの値が変更されたため、イベントが発生します。

  • _(scl'event and scl = '1')_に依存するコード行がある場合、誤ったトリガーを取得します。

  • rising_Edge(scl)に依存するコード行がある場合、誤ったトリガーを取得することはありません。

例の続き:「0」をSCLに割り当て、次に「Z」を割り当てます。 SCLネットは「0」になり、その後「H」に戻ります。

ここでは、「1」から「0」に移行してもどちらの場合もトリガーされませんが、「0」から「H」に移行するとrising_Edge(scl)条件(正しい)がトリガーされますが、_(scl'event and scl = '1')_ケースはそれを逃します(間違っています)。

一般的な推奨事項:

すべてのコードに_clk'event_の代わりにrising_Edge(clk)およびfalling_Edge(clk)を使用します。

11
Iain Waugh