81 lines
2.1 KiB
Verilog
81 lines
2.1 KiB
Verilog
`timescale 1 ns / 100 ps
|
|
module key_driver
|
|
(
|
|
input clk,
|
|
input rst,
|
|
input button_in,
|
|
output reg button_posedge,
|
|
output reg button_negedge,
|
|
output reg button_out
|
|
);
|
|
//// ---------------- internal constants --------------
|
|
parameter N = 32 ; // debounce timer bitwidth
|
|
parameter FREQ = 60; //model clock :Mhz
|
|
parameter MAX_TIME = 20; //ms
|
|
localparam TIMER_MAX_VAL = MAX_TIME * 1000 * FREQ;
|
|
////---------------- internal variables ---------------
|
|
reg [N-1 : 0] q_reg; // timing regs
|
|
reg [N-1 : 0] q_next;
|
|
reg DFF1, DFF2; // input flip-flops
|
|
wire q_add; // control flags
|
|
wire q_reset;
|
|
reg button_out_d0;
|
|
//// ------------------------------------------------------
|
|
|
|
////contenious assignment for counter control
|
|
assign q_reset = (DFF1 ^ DFF2); // xor input flip flops to look for level chage to reset counter
|
|
assign q_add = ~(q_reg == TIMER_MAX_VAL); // add to counter when q_reg msb is equal to 0
|
|
|
|
//// combo counter to manage q_next
|
|
always @ ( q_reset, q_add, q_reg) begin
|
|
case( {q_reset , q_add})
|
|
2'b00 :
|
|
q_next <= q_reg;
|
|
2'b01 :
|
|
q_next <= q_reg + 1;
|
|
default :
|
|
q_next <= { N {1'b0} };
|
|
endcase
|
|
end
|
|
|
|
//// Flip flop inputs and q_reg update
|
|
always @ ( posedge clk or posedge rst) begin
|
|
if(rst == 1'b1) begin
|
|
DFF1 <= 1'b0;
|
|
DFF2 <= 1'b0;
|
|
q_reg <= { N {1'b0} };
|
|
end
|
|
else begin
|
|
DFF1 <= button_in;
|
|
DFF2 <= DFF1;
|
|
q_reg <= q_next;
|
|
end
|
|
end
|
|
|
|
//// counter control
|
|
always @ ( posedge clk or posedge rst) begin
|
|
if(rst == 1'b1)
|
|
button_out <= 1'b1;
|
|
else if(q_reg == TIMER_MAX_VAL)
|
|
button_out <= DFF2;
|
|
else
|
|
button_out <= button_out;
|
|
end
|
|
|
|
always @ ( posedge clk or posedge rst) begin
|
|
if(rst == 1'b1) begin
|
|
button_out_d0 <= 1'b1;
|
|
button_posedge <= 1'b0;
|
|
button_negedge <= 1'b0;
|
|
end
|
|
else begin
|
|
button_out_d0 <= button_out;
|
|
button_posedge <= ~button_out_d0 & button_out;
|
|
button_negedge <= button_out_d0 & ~button_out;
|
|
end
|
|
end
|
|
|
|
endmodule
|
|
|
|
|