基于狀態機的設計代碼?
module key_filter(clk,rst,key,key_p_flag,key_r_flag,key_state);input clk,rst;input key;output reg key_p_flag;output reg key_r_flag;output reg key_state;reg [1:0]r_key; //后面用來判斷什么時候pedge,什么時候nedgealways@(posedge clk)r_key<={r_key[0],key}; //位拼接wire pedge_key;assign pedge_key=r_key==2'b01; //識別到key的上升沿wire nedge_key;assign nedge_key=r_key==2'b10; //識別到key的下降沿reg [19:0]cnt;localparam IDLE=0;reg [1:0]state;always@(posedge clk or negedge rst)if(!rst)beginstate<=0;key_r_flag<=0;key_p_flag<=0;cnt<=0;key_state<=1;endelse begin case (state)0:beginkey_r_flag<=0;if(nedge_key)state<=1;elsestate<=0;end1:if((pedge_key)&&(cnt<1000000-1))begincnt<=0;state<=0;end else if(cnt>=1000000-1)begin state<=2;cnt<=0; //給計數器清零,為下一次計數做準備key_p_flag<=1;key_state<=0;endelse beginstate<=1;cnt<=cnt+1;end 2:beginkey_p_flag<=0;if(pedge_key)state<=3;elsestate<=2;end 3:if((nedge_key)&&(cnt<1000000-1))beginstate<=2;state<=0;endelse if(cnt>=1000000-1) beginstate<=0;cnt<=0; //給計數器清零,為下一次計數做準備key_r_flag<=1;key_state<=1;endelse beginstate<=3;cnt<=cnt+1;endendcaseendendmodule
testbench代碼?
`timescale 1ns / 1psmodule key_filter_tb();reg clk,rst;reg key;wire key_p_flag;wire key_r_flag;wire key_state; key_filter key_filter(clk,rst,key,key_p_flag,key_r_flag,key_state);initial clk=1;always #10 clk=~clk;initial beginrst=0;key=1;#201;rst=1;#3000;key=0;#20000; //20ns,模擬按鍵抖動key=1;#30000; //30ns,模擬按鍵抖動key=0;#20000; //20ns,模擬按鍵抖動key=1;#30000; //30ns,模擬按鍵抖動key=0;#50000000; //50mskey=1;#20000; //20ns,模擬按鍵抖動key=0;#30000; //30ns,模擬按鍵抖動key=1;#20000; //20ns,模擬按鍵抖動key=0;#30000; //30ns,模擬按鍵抖動key=1;#50000000; //50ms $stop;end
endmodule
?仿真驗證波形
在按下抖動的過程中,key在抖動但是p_flag并沒有出現高脈沖?,直到穩定了20ms后p_flag出現了高脈沖。
?并只穩定了一個時鐘周期后就變為0
R_flag也是同樣
在輸出端再加入一個key_state,模擬什么時候確定按鍵按下,什么時候按鍵釋放