我只想计算按下按钮的次数。我尝试了两种方法,但它们都有“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;
谢谢。
答案 0 :(得分:0)
如上所述,在第一个代码中,你还没有Button_db_s的驱动程序。
在第二个代码中,也存在问题。例如,当您从状态Four移动到状态Zero时,您指定Cnt_But = 5,然后在状态为零时立即用Cnt_But = 0覆盖此值。无论如何,在使用有限状态机(FSM)方法设计电路时,忽略了最重要的阶段,即为其绘制详细的状态图。我在下面提供了一个可能的解决方案。
但请注意以下内容。
你说debouncer是由另一个电路提供的,所以在上面的FSM中就是这种情况(对于名为按钮的信号),但是debouncer可以嵌入到这台机器中
此外,假设计数器从0计数到最大值然后自动返回到零(这对于常规模2 ** N二进制计数器来说很好,其中N是计数器的FF数)。
请注意,这是递归计算机(输出 cnt ,是递归的)。下文参考1的第11章详细介绍了这种FSM。另一方面,好的去抖动者是定时(而不是递归)电路;定时FSM也在1第8章中详细介绍。
1 V. A. Pedroni,硬件中的有限状态机:理论与设计(使用VHDL和SystemVerilog),麻省理工学院出版社,2013年12月。