1

信号をラッチしたいのですが、ラッチしようとすると1サイクルの遅延が発生しますが、どうすればこれを回避できますか?

myLatch: process(wclk, we)   -- Can I ommit the we in the sensitivity list?
begin
    if wclk'event and wclk = '1' then
        lwe    <= we;
    end if;
end process;

ただし、これを試してシミュレーション中に波を調べると、lweはwclkの1サイクルだけ遅延します。tpで達成したいのは、の立ち上がりエッジでサンプリングwewclk、次の立ち上がりエッジまで安定させることだけです。次に、ラッチされた信号を、アーキテクチャで定義されている別のエンティティのポートマップに割り当てます。

==============================================

wclk'eventフリップフロップの代わりにラッチを取得するには、を省略しなければならないことがわかりました。これは私にはかなり直感的ではないようです。ラッチする信号をサンプリングする時間を短縮するだけで、ラッチからフリップフロップに移行します。なぜこれがなぜであり、私の認識が間違っているのかを誰かが説明できますか?(私はvhdlの初心者です)

4

3 に答える 3

2

まず、上に貼り付けたプロセスに関するいくつかの観察事項:

myLatch: process(wclk, we)
begin
  if wclk'event and wclk = '1' then
    lwe    <= we;
  end if;
end process;
  1. クロックプロセスを説明したため、感度リストから除外できるシグナル。このようなプロセスのセンシティビティ リストで必要な唯一のシグナルは、クロックと、非同期リセットを使用することを選択した場合です (同期リセットをセンシティビティ リストに追加する必要はありません)。

  2. を使用if wclk'event and wclk = '1' thenする代わりに、if rising_edge(wclk) thenorを使用する必要があります。if falling_edge(wclk) then理由については、良いブログ投稿があります

を省略するwclk'eventことにより、次のように、プロセスをクロックプロセスから組み合わせプロセスに変更しました。

myLatch: process(wclk, we)
begin
  if wclk = '1' then
    lwe    <= we;
  end if;
end process;

wclk組み合わせプロセスでは、すべての入力がセンシティビティ リストに存在する必要があるため、リストにとの両方を含めることは正しいでしょうwe。これらは出力に影響を与えるからです。通常lwe、ラッチの推測を避けるために if ステートメントのすべてのケースで が割り当てられていることを確認しますが、この場合は意図しているように見えます。

一般に、ラッチは避けるべきなので、ラッチが必要であることに気付いた場合は、一時停止してアプローチを検討する必要があります。Doulos には、ラッチに関するいくつかの記事あります

あなたが達成したいのは、の立ち上がりエッジでサンプリングwewclk、次の立ち上がりエッジまで安定させることだけだと述べました。以下のプロセスでこれを実現します。

  store : process(wclk)
  begin
    if rising_edge(wclk) then
      lwe <= we;
    end if;
  end process;

このプロセスにより、はの立ち上がりエッジごとにlweの値で更新され、1 クロック サイクルの間有効なままになります。wewclk

これで問題が解決するかどうかお知らせください。

于 2012-09-29T15:00:58.683 に答える
2

信じられないかもしれませんが、問題は実際にはテストベンチにあります。これは、VHDL シミュレーション モデルの動作に関係しています。

VHDL は通常、同期ハードウェア設計に使用されます。つまり、立ち上がりエッジでサンプリングし、立ち下がりエッジで出力を設定するフリップフロップを使用して、読み取りと書き込みの間に競合状態が発生しないようにします。しかし、VHDL では、このマスター/スレーブ ロジックは実際には反対のクロック エッジを使用してシミュレートされません。

プロセスを検討する

process (clock) begin
    if rising_edge(clock) then
        a <= b;
    end if;
end process;

シミュレーション タイムステップの開始時に、clockがちょうど上昇した場合、ifが実行されます。次に、割り当てa <= bが実行されます。これにより、すぐに割り当てが行われるわけではありませんが、タイムステップの終わりに割り当てをスケジュールします。

すべてのプロセスが実行された後、すべてのスケジュールされた割り当てが行われます。aこれは、次のタイムステップまでプロセスが の新しい値を「認識」しないことを意味します。

Time              a           b         Actions
Start of ts 1    '0'         '1'        a <= '1' is scheduled
End of ts 1      '1'         '0'        a <= '1' is executed
Start of ts 2    '1'         '0'        a <= '0' is scheduled
End of ts 2      '0'         '1'        a <= '0' is executed

したがって、波形ビューアーを見ると、a明らかにクロックの立ち上がりエッジに設定されており、b1 クロック サイクル遅れて続いていることがわかります。これが発生する原因となる割り当ての中間スケジューリングは表示されません。

もちろん、実際には「タイムステップの終わり」はなく、信号の実際の変化はa、フリップフロップのスレーブ部分がトリガーしたとき、つまり負のエッジで発生します。(おそらく、VHDL が負のエッジを使用する方が混乱しにくいかもしれませんが、まあ、これが機能する方法です)。

ラッチ コードの 2 つのテストベンチを次に示します。

最初に、波形ビューアを見ると、説明したとおりにlwe表示されます-1クロックサイクル遅れているように見えます-しかし、実際には、設定されている非ブロッキング割り当てで遅延が発生していますcounter-したがって、立ち上がりエッジが発生し、we実際にはまだ新しい値がありません。そして 2 番目では、そのような遅延は見られません。立ち上がりエッジで正確にその時lweの値に設定されます。we

Verilog の関連トピックについては、Verilog 合成でのノンブロッキング代入、キルするコーディング スタイルを参照してください。

于 2012-09-29T15:01:30.740 に答える
1

あなたが持っているプロセスは、あなたの説明によるとあなたが望むものですが、「私たち」は機密リストから削除する必要があります. これが期待どおりに機能しない場合は、ほぼ確実にテスト ベンチ/シミュレーションに問題があります。(Owen の回答を参照してください。) 具体的には、「we」の値を変更するのが遅すぎて、フリップフロップが新しい値ではなく前の値をラッチする可能性があります。

ただし、この信号のソースが何であるかを知りたいのですが、いつでも変更できる非同期信号の場合は、メタスタビリティから保護するためにロジックを追加する必要があります。

ラッチに関する 2 番目の質問に答えるには、wclk'event を省略するとラッチが発生するというのは正しいことです。ただし、このプロセスは、クロックの正の半周期全体で 'we' から 'lwe' への変更を伝達するため、希望どおりにはなりません。あなたの質問に対する簡単な答えは、このタイプの動作を実装するにはラッチが必要ですが、元のプロセスで説明されている動作にはフリップフロップが必要であるということです。

于 2012-10-01T11:05:12.777 に答える