0

こんにちは、VHDL を使用して簡単なマシンを実装しようとしていますが、ボタンの押下をデバウンスする必要があります。私の問題は、デバウンスをどこに実装すればよいかわからないことです。私の現在の仕事は次のようなものです。

process(clk)
begin
    if(clk' event and clk = '1') then
        if rst = '1' then
            curr_state <= state0;
        else
            curr_state <= next_state;
        end if;
    end if;
end process;

process(curr_state, op1,op0,rst)  --here op1,op0 and rst are all physical buttons and I need to debounce op1 and op0
begin
    if rst = '1' then
        ...some implementation
    else
        ...implement the debounce logic first
        ...process some input
        case curr_state is
            when state0=>...implementation
            ...similar stuff
        end case; 
end process;

自分のやり方が正しいかどうかはわかりません。2番目のプロセスでは、最初の処理をこのように入れるか、state0ブロックのときに中に入れますか? また、デバウンスの処理はカウントが必要なので、このようにケースブロックの外に出しますか?ありがとうございました!

4

2 に答える 2

2

ボタン信号をデバウンスするために完全に別のコード ブロックを使用することで、ステート マシン プロセスが他のことを気にすることなくステート マシンだけに集中できるようにします。

このようなプロセスを使用して、入力をデバウンスできます。もちろん、この例ではシグナルの変数を交換できます (関連する代入演算子の置換を使用)。

process (clk)
  constant DEBOUNCE_CLK_PERIODS : integer := 256;  -- Or whatever provides enough debouncing
  variable next_button_state : std_logic := '0';  -- Or whatever your 'unpressed' state is
  variable debounce_count : integer range 0 to DEBOUNCE_CLK_PERIODS-1 := 0;
begin
  if (rising_edge(clk)) then
    if (bouncy_button_in /= next_button_state) then
      next_button_state := bouncy_button_in;
      debounce_count := 0;
    else
      if (debounce_count /= DEBOUNCE_CLK_PERIODS-1) then
        debounce_count := debounce_count + 1;
      else
        debounced_button_out <= next_button_state;
      end if;
    end if;
  end if;
end process;

bouncy_button_in別のオプションは、遅いレートでサンプリングすることです。

process (clk)
  constant DEBOUNCE_CLK_DIVIDER : integer := 256;
  variable debounce_count : integer range 0 to DEBOUNCE_CLK_DIVIDER-1 := 0;
begin
  if (rising_edge(clk)) then
    if (debounce_count /= DEBOUNCE_CLK_DIVIDER-1) then
      debounce_count := debounce_count + 1;
    else
      debounce_count := 0;
      debounced_button_out <= bouncy_button_in;
    end if;
  end if;
end process;

最初の方法の利点は、入力のグリッチを拒否することです。どちらの場合も、ステート マシンで を使用し、そのコードにはコア ステート マシン機能のみが含まれますdebounced_button_outrst

さらにデバウンスが必要な場合は、別のカウンターを使用して上記のプロセスの有効信号を作成し、クロック レートを効果的に分割できます。これは、カウンターが特定のサイズを超えるとタイミングを満たすことができない可能性があるため、除算定数を非常に高い数値に設定するよりも優れている可能性があります。

ボタンごとにインスタンス化できる別のファイルにデバウンス エンティティを作成することもできます。上記のプロセスでは、定数のジェネリックを持つことができます。

ハードウェアのデバウンスもありますが、それはこの質問の範囲外だと思います。

于 2015-09-15T16:06:22.543 に答える
0

2番目のプロセスでは、最初の処理をこのように入れるか、state0ブロックのときに中に入れますか?

State0ブロックに入れるだけ

また、デバウンスの処理はカウントが必要なので、このようにケースブロックの外に出しますか?

カウントは、クロックされたプロセスで実行する必要があります。2 プロセスのステートマシンを実行しているため、ケース ブロックでは実行できません。とにかく、私は通常、これらの種類のリソースを別のクロックプロセスに配置します。

州の場合は、IS_0、TO_1、IS_1、TO_0 が必要です。
TO_1 と TO_0 は遷移状態です。16 ミリ秒の 1 が表示されると、TO_1 から IS_1 に移行します。16 ミリ秒間 0 が表示されると、TO_0 から IS_0 に遷移します。TO_1 または TO_0 状態のときにカウンターを実行します。IS_1 または IS_0 状態のときにカウンターをクリアします。

これにより、あなたが述べられるはずです。

于 2015-09-15T16:09:36.300 に答える