116 lines
2.8 KiB
Verilog
116 lines
2.8 KiB
Verilog
// Listing 5.6
|
|
module debounce
|
|
(
|
|
input wire clk, reset,
|
|
input wire sw,
|
|
output reg db
|
|
);
|
|
|
|
// symbolic state declaration
|
|
localparam [2:0]
|
|
zero = 3'b000,
|
|
wait1_1 = 3'b001,
|
|
wait1_2 = 3'b010,
|
|
wait1_3 = 3'b011,
|
|
one = 3'b100,
|
|
wait0_1 = 3'b101,
|
|
wait0_2 = 3'b110,
|
|
wait0_3 = 3'b111;
|
|
|
|
// number of counter bits (2^N * 10ns = 10ms tick)
|
|
localparam N =20;
|
|
|
|
// signal declaration
|
|
reg [N-1:0] q_reg;
|
|
wire [N-1:0] q_next;
|
|
wire m_tick;
|
|
reg [2:0] state_reg, state_next;
|
|
|
|
// body
|
|
|
|
//=============================================
|
|
// counter to generate 10 ms tick
|
|
//=============================================
|
|
always @(posedge clk)
|
|
q_reg <= q_next;
|
|
// next-state logic
|
|
assign q_next = q_reg + 1;
|
|
// output tick
|
|
assign m_tick = (q_reg==0) ? 1'b1 : 1'b0;
|
|
|
|
//=============================================
|
|
// debouncing FSM
|
|
//=============================================
|
|
// state register
|
|
always @(posedge clk, posedge reset)
|
|
if (reset)
|
|
state_reg <= zero;
|
|
else
|
|
state_reg <= state_next;
|
|
|
|
// next-state logic and output logic
|
|
always @*
|
|
begin
|
|
state_next = state_reg; // default state: the same
|
|
db = 1'b0; // default output: 0
|
|
case (state_reg)
|
|
zero:
|
|
if (sw)
|
|
state_next = wait1_1;
|
|
wait1_1:
|
|
if (~sw)
|
|
state_next = zero;
|
|
else
|
|
if (m_tick)
|
|
state_next = wait1_2;
|
|
wait1_2:
|
|
if (~sw)
|
|
state_next = zero;
|
|
else
|
|
if (m_tick)
|
|
state_next = wait1_3;
|
|
wait1_3:
|
|
if (~sw)
|
|
state_next = zero;
|
|
else
|
|
if (m_tick)
|
|
state_next = one;
|
|
one:
|
|
begin
|
|
db = 1'b1;
|
|
if (~sw)
|
|
state_next = wait0_1;
|
|
end
|
|
wait0_1:
|
|
begin
|
|
db = 1'b1;
|
|
if (sw)
|
|
state_next = one;
|
|
else
|
|
if (m_tick)
|
|
state_next = wait0_2;
|
|
end
|
|
wait0_2:
|
|
begin
|
|
db = 1'b1;
|
|
if (sw)
|
|
state_next = one;
|
|
else
|
|
if (m_tick)
|
|
state_next = wait0_3;
|
|
end
|
|
wait0_3:
|
|
begin
|
|
db = 1'b1;
|
|
if (sw)
|
|
state_next = one;
|
|
else
|
|
if (m_tick)
|
|
state_next = zero;
|
|
end
|
|
default: state_next = zero;
|
|
endcase
|
|
end
|
|
|
|
endmodule
|