VHDL:Mealy状态机中的按钮去抖动
嗨,我正在尝试使用VHDL实现一个mealy机器,但我需要取消按钮按下的影响。我的问题是我不确定我应该在哪里实现去抖动。我目前的工作是这样的:VHDL:Mealy状态机中的按钮去抖动,vhdl,fsm,debouncing,Vhdl,Fsm,Debouncing,嗨,我正在尝试使用VHDL实现一个mealy机器,但我需要取消按钮按下的影响。我的问题是我不确定我应该在哪里实现去抖动。我目前的工作是这样的: process(clk) begin if(clk' event and clk = '1') then if rst = '1' then curr_state <= state0; else curr_state <= next_state;
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;
过程(clk)
开始
如果(clk'事件和clk='1'),则
如果rst='1',则
curr_state我将使用一个完全独立的代码块来消除任何按钮信号的影响,允许您的状态机进程只关注状态机,而不必担心其他任何事情
您可以使用这样的过程来消除输入的影响。在本例中,您当然可以将变量交换为信号(使用相关的赋值运算符替换)
第一种方法的优点是它将拒绝输入中的小故障。在任何一种情况下,您都可以在状态机中使用“取消公告”按钮(或者您想叫它什么,也许是“代码>rst”
),其代码只包含核心状态机功能
如果您想要更多的去抖动,您可以使用另一个计数器为上述过程创建一个启用信号,以有效地划分时钟频率。这可能比将除法常数设置为一个非常高的数字要好,因为如果计数器超过一定的大小,您可能无法满足计时要求
您甚至可以在单独的文件中创建一个debounce实体,可以为每个按钮实例化该实体。在上面的过程中,它可以有一个常量的泛型
还有硬件去抖动,但我想这超出了这个问题的范围
在第二个过程中,我应该这样放置rst处理,还是
当state0阻塞时我应该把它放进去吗
只把它放在State0块中
另外,由于
debounce需要计数,我会把它放在箱子外面吗
这个
计数需要在计时过程中完成。由于您正在执行两进程状态机,因此无法在case块中执行。无论如何,我通常会将这些资源放在一个单独的计时进程中
对于州,您需要:IS_0、TO_1、IS_1、TO_0。TO_1和TO_0是过渡状态。当我看到一个1持续16毫秒时,我从到_1转换为IS_1。当我看到一个0持续16毫秒时,我从到_0转换为IS_0。当你处于到_1或到_0状态时,运行你的计数器。当您处于IS_1或IS_0状态时,清除计数器
这应该让你明白。不确定所有合成器都能正确处理你的第一个过程。我建议将
按钮状态
转换为一个信号,并将最后一个信号分配移到流程之外。谢谢@RenaudPacalet,我想我已经编辑了答案,因为你写了这个,如果不让我知道的话。
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;
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;