Vhdl-计数器有锁存器

时间:2014-01-08 19:11:42

标签: counter vhdl

我只想计算按下按钮的次数。我尝试了两种方法,但它们都有“Cnt_But”和“Current_state”信号的锁存器。

问题是“IF(Button_db_s ='1'和Button_db_ff_s ='0')然后”行。但是,该行允许我在“Rising_edge(时钟)”条件下只计数一次。

如果没有闩锁,我怎么能这样做?

1)

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
-------------------------------------------------------------------------------
Entity Tim3 is
Port(
Clock: in std_logic;
Reset: in std_logic;
Button: in std_logic
);
END Tim3;
-------------------------------------------------------------------------------
Architecture Tim3_a of Tim3 is
-------------------------------------------------------------------------------
Signal Button_db_s, Button_db_ff_s : std_logic:='0';
Signal Cnt_But : integer range 0 to 5 :=0;
BEGIN
-------------------------------------------------------------------------------
PROCESS(Clock, Reset)
BEGIN
    IF(Reset='1')Then
        Cnt_But<=0;
    ELSIF(Rising_Edge(Clock))Then   
        IF(Button_db_s='1' and Button_db_ff_s='0')Then      
            Cnt_But<=Cnt_But+1;
        END IF;
    END IF;         
END PROCESS;
-------------------------------------------------------------------------------
PROCESS(Clock,Reset) -- Button_db Flip Flop
BEGIN
    IF(Reset='1')Then
        button_db_ff_s<='0';
    ELSIF(Rising_Edge(Clock))Then
        button_db_ff_s<=button_db_s;
    END IF;
END PROCESS;
-------------------------------------------------------------------------------
End Tim3_a;

2)

PROCESS(Clock, Reset)
BEGIN
    IF(Reset='1')Then
        Cnt_But<=0;
        Current_state<=Zero;
    ELSIF(Rising_Edge(Clock))Then
            IF(Button_db_s='1' and Button_db_ff_s='0')Then
                Case current_state is
                    When Zero =>
                        IF(Button_db_s='1')Then
                            current_state<=One;
                            Cnt_But<=1;
                        ELSE
                            current_state<=Zero;
                            Cnt_But<=0;
                        END IF;

                    When One =>
                        IF(Button_db_s='1')Then
                            current_state<=Two;
                            Cnt_But<=2;
                        ELSE
                            current_state<=One;
                            Cnt_But<=1;
                        END IF;

                    When Two =>
                        IF(Button_db_s='1')Then
                            current_state<=Three;
                            Cnt_But<=3;
                        ELSE
                            current_state<=Two;
                            Cnt_But<=2;
                        END IF;

                    When Three =>
                        IF(Button_db_s='1')Then
                            current_state<=Four;
                            Cnt_But<=4;
                        ELSE
                            current_state<=Three;
                            Cnt_But<=3;
                        END IF;

                    When Four =>
                        IF(Button_db_s='1')Then
                            Current_state<=Zero;
                            Cnt_But<=5;
                            Error_2_s<='1'; -- Press only 4 times.
                        ELSE
                            Current_state<=Four;
                            Cnt_But<=4;
                        END IF;
                END CASE;
            END IF;
        END IF;
    END IF;         
END PROCESS;

谢谢。

1 个答案:

答案 0 :(得分:0)

如上所述,在第一个代码中,你还没有Button_db_s的驱动程序。

在第二个代码中,也存在问题。例如,当您从状态Four移动到状态Zero时,您指定Cnt_But = 5,然后在状态为零时立即用Cnt_But = 0覆盖此值。无论如何,在使用有限状态机(FSM)方法设计电路时,忽略了最重要的阶段,即为其绘制详细的状态图。我在下面提供了一个可能的解决方案。

enter image description here

但请注意以下内容。

  • 你说debouncer是由另一个电路提供的,所以在上面的FSM中就是这种情况(对于名为按钮的信号),但是debouncer可以嵌入到这台机器中

  • 此外,假设计数器从0计数到最大值然后自动返回到零(这对于常规模2 ** N二进制计数器来说很好,其中N是计数器的FF数)。

  • 请注意,这是递归计算机(输出 cnt ,是递归的)。下文参考1的第11章详细介绍了这种FSM。另一方面,好的去抖动者是定时(而不是递归)电路;定时FSM也在1第8章中详细介绍。

1 V. A. Pedroni,硬件中的有限状态机:理论与设计(使用VHDL和SystemVerilog),麻省理工学院出版社,2013年12月。