module pushbutton_debouncer(clk, pb, pb_state, pb_up, pb_down,rest);
input clk; // "clk" 時鐘訊號
input pb; // "pb" 有毛刺的、非同步的、低有效的按鍵訊號
input rest;
output pb_state; // 當按鍵被按下時輸出1
output pb_down; // 按鍵被按下的瞬間輸出乙個高電平脈衝
output pb_up; // 按鍵被鬆開的瞬間輸出乙個高電平脈衝
// 首先使用兩個觸發器來同步pb訊號
reg pb_sync_0; always @(posedge clk) pb_sync_0 <= ~pb; // 翻轉pb,使之高有效
reg pb_sync_1; always @(posedge clk) pb_sync_1 <= pb_sync_0;
// 宣告乙個16位的計數器
reg [15:0] pb_cnt;
// 當按鍵被按下或鬆開時,計數器計數
// 當計數器計數溢位時,便認為按鍵的狀態的確已經改變
reg pb_state; // 按鍵狀態 (0:鬆開, 1:按下)
wire pb_idle = (pb_state==pb_sync_1);
wire pb_cnt_max = &pb_cnt; //當pb_cnt為全1時,輸出為真
always @(posedge clk)
if(rest==0)
pb_state<=0;
else
if(pb_idle)
pb_cnt <= 0; // 沒發生任何事情
else
begin
pb_cnt <= pb_cnt + 1; // 按鍵被按下或者鬆開, 增加計數器的值r
if(pb_cnt_max) pb_state <= ~pb_state; // 如果計數器溢位,改變pb_state的值
endwire pb_down = ~pb_state & ~pb_idle & pb_cnt_max; // 當按鍵被按下時,有效乙個時鐘週期
wire pb_up = pb_state & ~pb_idle & pb_cnt_max; // 當按鍵被鬆開時,有效乙個時鐘週期
endmodule
使用16位的計數器、20mhz的時鐘,需要3ms的時間才能使計數器溢位。在使用者眼裡,3ms的時間很短,甚至來不及反應,但是毛刺卻正是在這3ms內被除去的。根據具體的按鍵和系統時鐘,你可能需要修改計數器的寬度。
FPGA按鍵防抖動程式 Verilog
module fangdoudong clk,reset,key in 1,key in 2,key in 3,led 1,led 2,led 3 input clk 50mhz input reset 高電平有效 input key in 1,key in 2,key in 3 開關key in ...
FPGA邏輯設計系列文章 模組劃分
1.fpga是自頂向下的設計模式,開始寫 時第一項面臨的就是模組劃分。模組劃分說容易就容易,說難就難,根據工程師的碼齡,可以分為下列幾種情況 第一階段 有啥好分的,就乙個.v檔案看著多方便 第二階段 寫的有點多啊,嘗試著分一下 第三階段 動手前,先想怎樣劃分 按a情況的劃分,介面端子數量太多啊 第四...
FPGA設計 VHDL語言篇 1 模組例化
關於模組例化有兩種方式,一種是通過宣告,在進行例化,另一種是直接進行例化操作,第一種可以通過configuration進行配置,便於統一管理配置,第二種呼叫方便,但不能通過configuration進行配置,不利於日後配置結構體。宣告 component port port1 port2 end c...