2017-02-27 2 views
1

入力信号としてプッシュボタンを使用するFPGAをプログラミングしています。これには、特定のボタン・プレスを使用して状態から状態に移行する11の状態を持つ有限状態マシンがあります。バウンスが解除され、連続的な状態遷移が発生する

たとえば、私の設計では、状態s0はボタンプレスを使用して状態s1になります。これは、状態s1からs2へ、および状態s2からs3への同じ移行ケースです。この状態遷移システムは、VHDLコードでcase文を使用して実装されています。

LEDは、ボードが現在あるどの状態を追跡するために、それぞれの状態で点灯します。

私の問題はmy_btnL =が「1」真であるとき、状態S0で、ボードは、それが移動したことを示しているということですs3を状態にする。

は何が起こっていると思うと、確かにS1とS2状態になるされているが、状態S0で同じボタンを押しても、状態S1およびS2に読み込まれているということです。これはボードが状態s1とs2のLED表示を表示するのに十分な時間がないほど速く起こります。状態s3は、異なるボタンを使用して状態s4に移動するので、状態s3で停止する。

は、だから私の質問はどのように私は、ボタン押下信号は、ボタンを1回押すだけで、それに続くものを立ち上がりエッジと立ち下がりエッジのように一つだけの状態で読み取るとされていないしていることを確認しますか?

プレスボタンの信号はディバウンスされますが、信号は均一な方形波になります。

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use ieee.numeric_std.all; 


entity digital_lock is 
    Port ( 
      my_btnC, clk, my_btnU, my_btnR, my_btnL, my_btnD: in std_logic; 
      my_sw: in std_logic_vector(3 downto 0); 
      hex0, hex1, hex2, hex3: out std_logic_vector (3 downto 0); 
      my_led: out std_logic_vector(15 downto 0) 
      ); 
end digital_lock; 

architecture Behavioral of digital_lock is 
type state IS (s0, s1, s2, s3, s4 ,s5 ,s6, s7, s8, s9, s10,s11); 

signal my_state: state; 
signal my_status: unsigned(1 downto 0); 
signal num1, num2, num3, key1, key2, key3: std_logic_vector(3 downto 0); 
signal number, final_key: std_logic_vector(11 downto 0); 

begin 

    FSM: process(clk, my_btnC) 
    begin 
    if(my_btnC ='1') then 
     my_state <= s0; 
    elsif rising_edge(clk) then 
     case my_state is 
      when s0 => 
       my_status <= "00"; 
       my_led <= "1100000000000000"; 
       hex3 <= "0000"; 
       hex2 <= "0000"; 
       hex1 <= "0000"; 
       hex0 <= "0000"; 
       if(my_btnL ='1') then 
        my_state <= s1; 
       else 
        my_state <= s0; 
       end if; 
      when s1 => 
       key1 <= my_sw; 
       hex0 <= key1; 
       my_led <= "0000000000000001"; 
       if(my_btnL='1') then 
        my_state <= s2; 
       else 
        my_state <= s1; 
       end if; 
      when s2 => 
       key2 <= my_sw; 
       hex0 <= key2; 
       my_led <= "0000000000000010"; 
       if(my_btnL ='1') then 
        my_state <= s3; 
       else 
        my_state <= s2; 
       end if; 
      when s3 => 
       key3 <= my_sw; 
       hex0 <= key3; 
       my_led <= "0000000000000011"; 
       if(my_btnR= '1') then 
        my_state <= s4; 
       else 
        my_state <= s3; 
       end if; 
      when s4 => 
       final_key(11 downto 8) <= key1; 
       final_key(7 downto 4) <= key2; 
       final_key(3 downto 0) <= key3; 
       my_led <= "0000000000000100"; 
       if(my_btnU ='1') then 
        my_state <= s5; 
       else 
        my_state <= s4; 
       end if; 
      when s5 => 
       num1 <= my_sw; 
       hex0 <= num1; 
       my_led <= "0000000000000101"; 
       if(my_btnD ='1') then 
        my_state <= s0; 
       elsif (my_btnL ='1') then 
        my_state <= s6; 
       else 
        my_state <= s5; 
       end if; 
      when s6 => 
       num2 <= my_sw; 
       hex0 <= num2; 
       my_led <= "0000000000000110"; 
       if(my_btnD ='1') then 
        my_state <= s0; 
       elsif(my_btnL ='1') then 
        my_state <= s7; 
       else 
        my_state <= s6; 
       end if; 
      when s7 => 
       num3 <= my_sw; 
       hex0 <= num3; 
       my_led <= "0000000000000111"; 
       if(my_btnD ='1') then 
        my_state <= s0; 
       elsif(my_btnR = '1') then 
        my_state <= s8; 
       else 
        my_state <= s7; 
       end if; 
      when s8 => 
       number(11 downto 8) <= num1; 
       number(7 downto 4) <= num2; 
       number(3 downto 0) <= num3; 
       my_led <= "0000000000001000"; 
       if(number = final_key) then 
        my_state <= s9; 
       else 
        my_state <= s10; 
       end if; 
      when s9 => 
       my_led <= "1111111111111111"; 
       if(my_btnD = '1') then 
        my_state <= s0; 
       else 
        my_state <= s9; 
       end if; 
      when s10 => 
       my_status <= my_status + 1; 
       if(my_status >= 3) then 
        my_state <= s11; 
       elsif(my_status < 3) then 
        my_state <= s5; 
       end if; 
      when s11 => 
       my_led <= "0000000000000000"; 
       hex0 <= "1111"; 
       hex1 <= "1111"; 
       hex2 <= "1111"; 
       hex3 <= "1111"; 
       my_state <= s11; 
     end case; 
     end if; 
    end process; 
end Behavioral; 
+1

あなたの仮説が有効な音やシミュレーションによって試験することができます。 – user1155120

答えて

2

状態マシンと同じクロック・ドメインでデバウンス信号のためのエッジ検出を行うことができる次のコードbtnC、btnL、btnRで

、...プッシュボタンでありますフリップフロップが他の状態にある間に、入力端(入力端に続く)上の好ましい状態を検出する信号入力とゲートを有するフリップフロップとを含む。

signal my_btnL_event: std_logic; 
signal my_btnLd:  std_logic; -- architecture declarative items 

process (clk) 
begin 
    if rising_edge(clk) then 
     my_btnLd <= my_btnL; 
    end if; 

my_btnL_event <= my_btnL and not my_btnLd; 

ここでは、状態間の移行にmy_btnLの代わりにmy_btnL_eventを使用します。

注これは、適切なデバウンスを想定して再び有効に行く前にinvaid行きmy_btnLを必要とします。

my_btnL_eventの割り当ては、if文や条件付きシグナル割り当てなど、複数の方法で表現できます。何が起こっているのかについての

+1

私はcase文の前にこのコードブロックを入れる必要がありますか? – Flower

+2

宣言は、アーキテクチャが始まる前に行われます。代入ステートメントとプロセスは並行ステートメントで、プロセスの前でも後でも構いません。エッジ検出する他のボタンがありますが、my_btnCではなく、リセットとして使用されます。 – user1155120

関連する問題