1

スイッチとキーを含む常にブロックがあります。機密リストにキーしかない場合、正常に動作します (コードを 1 回だけ実行してからブロックを終了します)。スイッチを感度リストに追加すると、キーが押されていないときにトリガーするだけなのに、キーを押している間はおかしくなり、無期限にループしているように見えます。

キーを押すたびに1回だけインクリメントするカウンターを実装しようとしています。

センシティビティ リストにキーのみを含む作業コードを次に示します (sw[1] は、カウントアップまたはカウントダウンのどちらであるかを示します)。

always @ (negedge key[2]) begin
  if (~key[2]) 
      begin
        if (sw[1] == 0) begin
          if (p3ctr == 15) p3ctr = 0;
          else p3ctr = p3ctr + 1;
        end
        else if (sw[1] == 1) begin
          if (p3ctr == 0) p3ctr = 15;
          else p3ctr = p3ctr - 1;
        end
    end
end

壊れたコードは次のとおりです (スイッチがオンになったときにカウンタをリセットするために sw[7] を使用しています。キー [2] が押されている間、このコードは無期限にループします)。

always @ (negedge key[2] or posedge sw[7]) begin
  if (~key[2]) 
      begin
        if (sw[1] == 0) begin
          if (p3ctr == 15) p3ctr = 0;
          else p3ctr = p3ctr + 1;
        end
        else if (sw[1] == 1) begin
          if (p3ctr == 0) p3ctr = 15;
          else p3ctr = p3ctr - 1;
        end
    end
  else begin
    p3ctr = 0;
  end
end

センシティビティ リストのシグナルが変更されたときに、always ブロック内のコードが 1 回だけ実行されると思っていましたが、明らかにそうではありません。

キーを押すたびにこのコードを1回だけ実行して、カウンターが適切に動作するようにする方法はありますか?

ありがとう!

4

1 に答える 1

2

FPGA で実行しているときに問題が発生していると思います。純粋なシミュレーションは問題ないように見えます。合成ツールは、最初ifが非同期ロジックであると想定しており、else条件は適切なコーディング スタイルであるため、同期ロジックとして扱われます。提供されたコードの最初の条件はif (~key[2])、合成ツールがnegedge key[2]アクティブ Low の非同期ロジックとして扱うことを意味します。リセット条件if (sw[7])から開始すると、目的の結果が得られるはずです。

always @ (negedge key[2] or posedge sw[7]) begin
  if (sw[7]) begin
    p3ctr <= 0;
  end
  else begin
    if (sw[1] == 0) begin
      if (p3ctr == 15) p3ctr <= 0;
      else p3ctr <= p3ctr + 1;
    end
    else if (sw[1] == 1) begin
      if (p3ctr == 0) p3ctr <= 15;
      else p3ctr <= p3ctr - 1;
    end
  end
end

注: ノンブロッキング代入 ( <=) をフロップで使用するのがベスト プラクティスです。ブロッキング割り当て ( =) は組み合わせロジック用です。

于 2013-11-03T19:01:45.350 に答える